ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ReentrantLock与synchronized的区别

2022-05-28 02:01:34  阅读:187  来源: 互联网

标签:synchronized 区别 lock ReentrantLock 线程 Lock 执行 方法


Synchronized

Synchronized 是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本质又是依赖于底层的操作系统的 Mutex Lock(互斥锁)来实现的。而操作系统实现线程之间的切换需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么 Synchronized 效率低的原因。因此,这种依赖于操作系统 Mutex Lock 所实现的锁我们称之为 “重量级锁”

同步方法通过ACC_SYNCHRONIZED 关键字隐式的对方法进行加锁。当线程要执行的方法被标注上ACC_SYNCHRONIZED时,需要先获得锁才能执行该方法。
同步代码块通过monitorenter和monitorexit执行来进行加锁。当线程执行到monitorenter的时候要先获得锁,才能执行后面的方法。当线程执行到monitorexit的时候则要释放锁。每个对象自身维护着一个被加锁次数的计数器,当计数器不为0时,只有获得锁的线程才能再次获得锁。

ReentrantLock

ReentrantLock通过原子操作和阻塞实现锁原理,一般使用lock获取锁,unlock释放锁

lock的时候可能被其他线程获得所,那么此线程会阻塞自己,关键原理底层用到Unsafe类的API: CAS和park

ReentantLock 继承接口Lock 并实现了接口中定义的方法,他是一种可重入锁,除了能完
成synchronized 所能完成的所有工作外,还提供了诸如可响应中断锁、可轮询锁请求、定时锁等
避免多线程死锁的方法。

 

Lock 主要方法
1. void lock(): 执行此方法时, 如果锁处于空闲状态, 当前线程将获取到锁. 相反, 如果锁已经
被其他线程持有, 将禁用当前线程, 直到当前线程获取到锁.
2. boolean tryLock():如果锁可用, 则获取锁, 并立即返回true, 否则返回false. 该方法和
lock()的区别在于, tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程被禁用,
当前线程仍然继续往下执行代码. 而lock()方法则是一定要获取到锁, 如果锁不可用, 就一
直等待, 在未获得锁之前,当前线程并不继续向下执行.
3. void unlock():执行此方法时, 当前线程将释放持有的锁. 锁只能由持有者释放, 如果线程
并不持有锁, 却执行该方法, 可能导致异常的发生.
4. Condition newCondition():条件对象,获取等待通知组件。该组件和当前的锁绑定,
当前线程只有获取了锁,才能调用该组件的await()方法,而调用后,当前线程将缩放锁。

ReentrantLock 与 synchronized

1.ReentrantLock 通过方法lock()与unlock()来进行加锁与解锁操作,与synchronized 会
被JVM 自动解锁机制不同,ReentrantLock 加锁后需要手动进行解锁。为了避免程序出
现异常而无法正常解锁的情况,使用ReentrantLock 必须在finally 控制块中进行解锁操
作。
2. ReentrantLock 相比synchronized 的优势是可中断、公平锁、多个锁。这种情况下需要
使用ReentrantLock。

 

wait() notify() notifyAll() 和await() signal() 和 signalAll() 的区别?

在使⽤Lock之前,我们都使⽤Object+的wait和notify实现同步。

Synchronized(obj){

obj.wait://此时这个线程会释放锁。并等待其他线程唤醒才能往下执行。

}

Synchronized(obj){

obj.notify://此时这个线程会释放锁。并等待其他线程唤醒才能往下执行。

}

而Lock则是由Lock控制锁,Condition来控制被阻塞线程

// 消费者
lock.lock();

condition.await();
lock.unlock();


//生产者
lock.lock();
condition.signal();
lock.unlock();

为了突出区别,省略了若⼲细节。区别有三点:

1.lock不再使用synchronize把同步代码包装起来

2.阻塞需要另外一个对象condition。

3.对应的方法是await和signal。

使用lock的好处就是我们可以指定条件来唤醒某个线程。而object 的唤醒是随机的

假设我们我们的需要想让a线程执行。

Lock lock = new ReentrantLock();

Condition acondition=lock.newCondition();//创建Condition

Condition bcondition=lock.newCondition();//创建Condition

可以acondition.signal().这样a线程就可以唤醒了。

 

标签:synchronized,区别,lock,ReentrantLock,线程,Lock,执行,方法
来源: https://www.cnblogs.com/wmdshijie/p/16319706.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有