当前位置:网站首页>synchronized 和 ReentrantLock

synchronized 和 ReentrantLock

2022-07-06 00:33:00 InfoQ

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() 释放锁,使用代码:

Lock lock = new ReentrantLock();
try {
 lock.lock();
} finally {
 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]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/0786171a23a7dd246d2975fa8