java5以后,新增了显式锁,用于当内置锁不能满足需求后可选择的一种高级方案。
lock接口的特点
与内置锁一样,他能提供互斥性,内存可见性,可重入等特征,与内置锁不同的是,Lock提供了一种无条件,可轮询,定时的,可中断的锁获取操作,以及公平队列,非块结构锁,所有的操作都是显式的。
lock和内置锁如何选择
因为显式锁提供了如上的特点。也就是说,仅当内置锁无法满足要求的时候,才考虑Lock,内置锁是jvm的属性,能做一些优化???(?未来更有可能优化内置锁,而非显式锁?)
Lock的常用实现ReentrantLock。
- 常用的api: tryLock,lock,lockInterruptibly
-
构造函数提供了公平和非公平锁,通常非公平锁的效率比公平锁高
公平锁:线程按照请求的顺序来获取锁。
非公平:当一个线程请求非公平锁时,如果发出请求的同时,该锁变成释放,那么该线程就将跳过所有队列,进而获取锁。如果该锁是被其他线程持有,那么该请求才会进入队列。
Lock和synchronize性能方面
如果越多的资源耗费在锁的管理和调度上,那么应用程序的得到的资源就越少。锁的方式越好,系统调用和上下文切换就越少,共享内存总线上的内存同步通信量就越少。java6后,synchronize的优化,使得在性能上和显式锁并不会有太大的差别。
读写锁ReadWriterLock
实现ReentrantlockReadWriteLock。
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading.
*/
Lock readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing.
*/
Lock writeLock();
}
顾名思义,在多数并发操作中,如果读的频率多于写,那么一般情况下,多处理器下采用读写锁能提高更好的并发,其他情况独占锁更好。但是这个结论必须经过测试,对程序进行分析。如果发现并没有提高多少性能,那么推荐使用独占锁。