六 多线程问题
问题1: 什么是Re-entrant Lock
锁的acquire是per thread 的, 而不是per call的,也就是同一个线程再次申请已经获得的锁,直接成功返回。如果是非re-entrant的锁,一个线程试图获取已经获得的锁会死锁,因为当前线程会挂起,没有机会release锁
synchronized的锁和 ReentrantLock都是 Re-entrant Lock。
问题2: java已经有了synchronized,为什么还要在jdk1.5中加入Lock系列?
ReentrantLock 和 synchronized有相同的语义,但是有更高的性能,ReentrantLock 使用原子变量来维护等待锁定的线程队列。
synchronized获取锁的时候只能一直等,没有超时机制,也不能被打断,而且锁的获取和释放必须在一个方法内
而ReentrantLock的lock方法和synchronized是等同语义的,还可以通过tryLock等方法有多种选择,并且以接口和类的形式而不是语言feature的形式存在,更好扩展。
- public interface Lock {
- void lock();
- void lockInterruptibly() throws InterruptedException;
- boolean tryLock();
- boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
- void unlock();
- Condition newCondition();
- }
Lock的确缺点是必须在finally块中 unlock
问题7 用ReentrantLock代替synchronized后, 需要用wait, notify的时候怎么办?
wait和notify是synchronized用的, ReentrantLock使用condition的await和singal。
问题8 锁的等待队列,是先申请的线程先获取吗?