synchronized 和 ReentrantLock
synchronized 和 ReentrantLock 有什么区别?
synchronized:synchronized 属于独占式的悲观锁,是通过 JVM 实现,synchronized 在同一时刻只允许一个线程操作资源。
ReentrantLock:ReentrantLock 是 Lock 的默认实现方式之一,它是基于 AQS 实现的,默认是非公平,内部有一个 state 的状态字段用于表示锁是否被占用,如果是 0 则表示锁未被占用,当线程把 state 改为 1,则表示线程成功获得了锁,其他线程则需要排队等待获取锁。
synchronized 和 ReentrantLock 都提供了锁的功能
ReentrantLock 可设置为公平锁,而 synchronized 不能
ReentrantLock 只能修饰代码块,而 synchronized 可以用于修饰方法、修饰代码块等;
ReentrantLock 需要手动加锁和释放锁,锁没有释放,则会造成资源被占用一直得不到释放,而 synchronized 无需手动释放锁,由 jvm 内部自动加锁和释放锁
ReentrantLock 可以主动的获取是否成功获得了锁的信息,而 synchronized 不行,可以理解为黑盒方法
使用
ReentrantLock 的使用:ReentrantLock 是通过 lock() 来获取锁,通过 unlock() 释放锁,使用代码:
synchronized 的使用:
直接修饰在方法声明上
声明在方法块中
原理的区别
Synchronized 由 monitorenter 实现:
每个对象有一个锁 monitor,当 monitor 被占用时就会处于锁定状态
如果 monitor 的进入数为 0,则该线程进入 monitor,然后将进入数设置为 1,该线程即为 monitor 的所有者
如果 monitor 的进入数不为 0,则表示已有线程进入 monitor,则该线程进入阻塞状态
线程执行完成后,退出 monitor,将进入数设置为 0
ReenTrantLock 由 CAS+CLH 队列来实现:
CAS:Compare and Swap,比较并交换,此操作为一个原子操作
CLH 队列:带头结点的双向非循环链表
版权声明: 本文为 InfoQ 作者【zarmnosaj】的原创文章。
原文链接:【http://xie.infoq.cn/article/0786171a23a7dd246d2975fa8】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论