写点什么

synchronized 和 ReentrantLock

作者:zarmnosaj
  • 2022 年 7 月 05 日
  • 本文字数:736 字

    阅读完需:约 2 分钟

synchronized 和 ReentrantLock 有什么区别?

synchronized:synchronized 属于独占式的悲观锁,是通过 JVM 实现,synchronized 在同一时刻只允许一个线程操作资源。


ReentrantLock:ReentrantLock 是 Lock 的默认实现方式之一,它是基于 AQS 实现的,默认是非公平,内部有一个 state 的状态字段用于表示锁是否被占用,如果是 0 则表示锁未被占用,当线程把 state 改为 1,则表示线程成功获得了锁,其他线程则需要排队等待获取锁。


  1. synchronized 和 ReentrantLock 都提供了锁的功能

  2. ReentrantLock 可设置为公平锁,而 synchronized 不能

  3. ReentrantLock 只能修饰代码块,而 synchronized 可以用于修饰方法、修饰代码块等;

  4. ReentrantLock 需要手动加锁和释放锁,锁没有释放,则会造成资源被占用一直得不到释放,而 synchronized 无需手动释放锁,由 jvm 内部自动加锁和释放锁

  5. ReentrantLock 可以主动的获取是否成功获得了锁的信息,而 synchronized 不行,可以理解为黑盒方法

使用

ReentrantLock 的使用:ReentrantLock 是通过 lock() 来获取锁,通过 unlock() 释放锁,使用代码:


Lock lock = new ReentrantLock();try {    lock.lock();} finally {    lock.unlock();}
复制代码


synchronized 的使用:


  1. 直接修饰在方法声明上

  2. 声明在方法块中

原理的区别

Synchronized 由 monitorenter 实现:


  1. 每个对象有一个锁 monitor,当 monitor 被占用时就会处于锁定状态

  2. 如果 monitor 的进入数为 0,则该线程进入 monitor,然后将进入数设置为 1,该线程即为 monitor 的所有者

  3. 如果 monitor 的进入数不为 0,则表示已有线程进入 monitor,则该线程进入阻塞状态

  4. 线程执行完成后,退出 monitor,将进入数设置为 0


ReenTrantLock 由 CAS+CLH 队列来实现:


  1. CAS:Compare and Swap,比较并交换,此操作为一个原子操作

  2. CLH 队列:带头结点的双向非循环链表

发布于: 刚刚阅读数: 3
用户头像

zarmnosaj

关注

靡不有初,鲜克有终 2020.02.06 加入

成都后端混子

评论

发布
暂无评论
synchronized 和 ReentrantLock_7月月更_zarmnosaj_InfoQ写作社区