Java Lock
Synchronized 的缺陷
当使用 Synchronzied 修饰代码块时,一个线程获取对象时,其他线程只能等待。如果这个线程由于等待IO或者其他原因被阻塞了,但是又没有释放锁,将严重影响程序执行效率。
java.util.concurrent.locks.Lock 提供了另外一种更加灵活的同步方案。
1.一个线程获取锁时,可以设置一个等待时间,不会让其他线程无限期的等待下去
2.取得前线程是否获得锁的状态,tryLock() 3.在读写操作,读线程之间不需要进行同步操作,以提高性能 4.Lock可以让等待锁的线程响应中断(在获取不到锁时终止等待状态)
Lock 与 ReenTrantLock
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException; // 可响应中断
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException; // 在指定的时间未获得锁时,返回false
void unlock();
Condition newCondition();
}
Lock l = ...;
l.lock();
try {
// do something...
} finally {
l.unlock();
}
ReadWriteLock 和 ReentrantReadWriteLock
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
一些注意点
- synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
- Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
- Lock可以提高多个线程进行读操作的效率。