Synchronized和ReentrantLock都是 Java 中用于实现多线程同步的机制,它们有以下区别:
相同点:
- 它们都是加锁方式同步,
- 并且都是阻塞式的同步,也就是说当如果一个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待,而进行线程阻塞和唤醒的代价是比较高的(操作系统需要在用户态与内核态之间来回切换,代价很高,不过可以通过对锁优化进行改善)
- 都是可重入锁
不同点:
- Synchronized是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成
- Synchronized的使用比较方便简洁,并且由编译器去保证锁的加锁和释放,而ReenTrantLock需要手工声明来加锁和释放锁(为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁)
- Synchronized锁的范围是整个方法或synchronized块部分,ReentrantLock因为是方法调用,可以跨方法,灵活性更好。(锁的细粒度和灵活度方面,ReenTrantLock优于Synchronized)
- 性能方面,Synchronized优化之前,Synchronized性能比ReenTrantLock差。到jdk1.6,Synchronized优化之后,
Synchronized引入了偏向锁(偏向锁即操作流程偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步),轻量级锁(自旋锁)后,两者的性能就差不多了,synchronized的优化我感觉借鉴了ReenTrantLock中的CAS技术。都是试图在用户态(不能获取CPU)就把加锁问题解决,避免进入内核态(可以获取CPU上下文切换)的线程阻塞。
© 版权声明
相关文章
暂无评论...