ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## concurrent包的设计 ![](https://img.kancloud.cn/22/a1/22a1623ed0d6f4ac7109d9cd62692411_983x681.png) 在上图中,我们大致可以看出courrent包下的整体结构。整个包大致分为了三层。 * 高层:Lock、同步器、阻塞队列等。 * 中层:AQS(AbstractQueuedSynchronizer)、非阻塞数据结构、原子变量类(java.util.concurrent.atomic包中的类)。 * 底层:volatile变量的读/写、CAS操作。 其中每个层中的依赖关系也很明显,AQS,非阻塞数据结构和原子变量类(java.util.concurrent.atomic包中的类),都是基于底层实现,而高层类又依赖中层这些基础类 ## Lock 接口 | 方法名称| 描述| | --- | --- | |void lock()|获取锁. 成功则向下运行,失败则阻塞| |void lockInterruptibly() throws InterruptedException|可中断地获取锁,在当前线程获取锁的过程中可以响应中断信号| |boolean tryLock()|尝试非阻塞获取锁,调用方法后立即返回,成功返回true,失败返回false| |boolean tryLock(long time, TimeUnit unit) throws InterruptedException|在超时时间内获取锁,到达超时时间将返回false,也可以响应中断| |void unlock();| 释放锁| |Condition newCondition();|获取等待通知组件实现信号控制,等待通知组件 ## 优点 > **synchronized的同步是jvm底层实现的**,借助物理设备的指令控制,对一般程序员来说程序遇到出乎意料的行为的时候,除了查官方文档几乎没有别的办法;**而显示锁除了个别操作用了底层的Unsafe类之外,几乎都是用java语言实现的** 相比synchronized,Lock增加了一些高级功能,主要有以下3项: **等待可中断** 指当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情,可中断特性对处理执行时间非常长的同步块很有帮助。 **公平锁** 指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁;而非公平锁则不保证这一点,在锁被释放时,任何一个等待锁的线程都有机会获得锁。 synchronized中的锁是非公平的,ReentrantLock默认情况下也是非公平的,但可以通过带布尔值的构造函数要求使用公平锁。 **锁绑定多个条件** 指一个ReentrantLock对象可以同时绑定多个Condition对象,而在synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件,如果要和多于一个的条件关联的时候,就不得不额外地添加一个锁,而ReentrantLock则无须这样做,只需要多次调用newCondition()方法即可。 **java实现** synchronized的同步是jvm底层实现的,借助物理设备的指令控制,对一般程序员来说程序遇到出乎意料的行为的时候,除了查官方文档几乎没有别的办法;而显示锁除了个别操作用了底层的Unsafe类之外,几乎都是用java语言实现的 ## 缺点 **使用比较复杂** 这点之前提到了,需要手动加锁,解锁,而且还必须保证在异常状态下也要能够解锁。而synchronized的使用就简单多了。 **效率较低** synchronized关键字毕竟是jvm底层实现的,因此用了很多优化措施来优化速度(偏向锁、轻量锁等),而显示锁的效率相对低一些。 ## 总结 因此当需要进行同步时,优先考虑使用synchronized关键字,只有synchronized关键字不能满足需求时,才考虑使用显示锁。 ## 参考资料 [Java并发编程:Lock显示锁](https://blog.csdn.net/fei20121106/article/details/83268499)