Java并发编程经典题目
第一部分:理论篇
多线程
Q:java中有几种方法可以创建一个线程?
how many ways to create a thread in java
Q:如何停止一个正在运行的线程?
Q:notify()和notifyAll()有什么区别?
notify()是唤醒一个线程。只唤醒一个。
notifyAll()是唤醒全部线程,但是注意是一个个唤醒,唤醒一个再唤下一个。
随机唤醒和唤醒全部。
Q:sleep()和 wait()有什么区别?
定时等待和在监视器上等待,不同范畴。
Q:什么是Daemon线程?它有什么意义?
守护线程,不需要上层逻辑介入的后台线程 ,比如GC。
Q:java如何实现多线程之间的通讯和协作?
中断和 直接或间接访问对方实例。
线程同步(使用了synchronized)和线程通讯(使用了wait,notify)
锁
Q:什么是可重入锁(ReentrantLock)?
更高级的锁,附加更多特性。
Q:当一个线程进入某个对象的一个synchronized的实例方法后,其它线程是否可进入此对象的其它方法?
可进入非synchronized方法。
Q:synchronized和java.util.concurrent.locks.Lock的异同?
后者具有更丰富的特性。
ReentrantLock 相对于固有锁synchronized,同样是可重入的,在某些vm版本上提供了比固有锁更高的性能,提供了更丰富的锁特性,比如可中断的锁,可等待的锁,平等锁以及非块结构的加锁。从代码上尽量用固有锁,vm会对固有锁做一定的优化,并且代码可维护和稳定。只有在需要ReentrantLock的一些特性时,可以考虑用ReentrantLock实现。
ReentrantLock 和synchronized比较:
性能上:
synchronized在Java5.0性能大胜synchronized,Java 6中synchronized 略有胜出—-摘自《Java并发编程实战》(13.4)
当时我说synchronized在今后的JVM(JIT)优化的可能性比ReentrantLock大,回来后我翻翻资料,发现在ReentrantLock 和synchronized还真有一些需要了解的知识,所以特别整理下发给大家。
1.为什么JUC框架出现LOCK?
ReentrantLock并不是替代synchronized的方法,而是当内置锁不适用时,作为一种可选的高级功能。
2.那么Synchronized有哪些缺点?
①. 只有一个condition与锁相关联,这个condition是什么?就是synchronized对针对的对象锁。
②. synchronized无法中断一个正在等待获得锁的线程,也即多线程竞争一个锁时,其余未得到锁的线程只能不停的尝试获得锁,而不能中断。这种情况对于大量的竞争线程会造成性能的下降等后果。
可见ReentrantLock 是对synchronized补充。
3.我们面对ReentrantLock和synchronized改如何选择?
Synchronized相比Lock,为许多开发人员所熟悉,并且简洁紧凑,如果现有程序已经使用了内置锁,那么尽量保持代码风格统一,尽量不引入Lock,避免两种机制混用,容易令人困惑,也容易发生错误。
在Synchronized无法满足需求的情况下,Lock可以作为一种高级工具,这些功能包括“可定时的、可轮询的与可中断的锁获取操作,公平队列,以及非块结构的锁”否则还是优先使用Synchronized。
最后,未来更可能提升Synchronized而不是Lock的性能,因为Synchronized是JVM的内置属性,他能执行一些优化,例如对线程封闭的锁对象的锁消除优化,通过增加锁的粒度来消除内置锁的同步,而如果基于类库的锁来实现这些功能,则可能性不大。—以上建议摘自《java并发编程实战》(13.4)
Q:乐观锁和悲观锁的理解及如何实现,有哪些实现方式?
乐观锁是假设我已经拿到锁,悲观所是我必须拿到锁,前者用CAS,后者用mutex。
并发框架
Q:SynchronizedMap和ConcurrentHashMap有什么区别?
后者具有更高的并发。
Q:CopyOnWriteArrayList可以用于什么应用场景?
多读少写。