ReentrantLock介绍【1】ReentrantLock是一种基于AQS框架的应用实现,是JDK中的一种线程并发访问的同步手段,它的功能类似于synchronized是一种互斥锁,可以保证线程安全 。
【2】相对于 synchronized,ReentrantLock具备如下特点:
1)可中断2)可以设置超时时间3)可以设置为公平锁4)支持多个条件变量5)与 synchronized 一样,都支持可重入ReentrantLock问题分析【1】ReentrantLock公平锁和非公平锁的性能谁更高?
1)那肯定是非公平锁,但是为什么是非公平更高呢?
2)因为涉及到了线程的park()与unpark()操作,不管是ReentrantLock还是synchronized,都在避免这些操作 。
(1)如ReentrantLock的非公平同步器在得不到锁的情况下,即将要进入之前会再加一次锁,生成节点之后又会加一次锁,把节点放入队列之后又会加一次锁,最终迫不得已才会进行park()操作 。
(2)如synchronized,在生成monitor的过程之中也会多次尝试加锁,避免monitor的生成 。
【深入理解独占锁ReentrantLock类锁】3)为什么要避免呢?这就涉及到线程的概念了 。
(1)因为park()与unpark()操作涉及到了线程的上下文切换,同时又涉及到了时间片轮转机制 。
(2)线程上下文切换,需要将旧的线程资源保存回内存【保存执行到了哪一步,需要什么东西】,将新的线程的资源加载入CPU,让新线程具备执行的资源并开始执行 。但是这些操作都是需要花费时间的,会消耗一部分时间片的资源 。如(这里仅仅只是举例说明),一个时间片本来就是50s,你拿到的时候花费了一定的时间(如10s)进行上下文切换,现在刚执行不到5s,你又要进行一次切换(又要花费10s) 。那下一个拿到时间片的线程会不会还是会继续切换呢?而且你要下次运行就又要等时间片了 。
(3)所以说,本质上非公平机制是为了让持有CPU的线程尽可能多的做有用的任务,减少上线下文切换带来的开销,毕竟时间片来之不易,本身就是从众多线程之中好不容易分配得来的 。
ReentrantLock的使用【1】使用模板
Lock lock = new ReentrantLock();//加锁lock.lock();try {// 临界区代码// TODO 业务逻辑:读写操作不能保证线程安全} finally {// 解锁,放置在这里的原因是保证异常情况都不能干扰到解锁逻辑lock.unlock();}【2】可重入的尝试
public class ReentrantLockDemo {public static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) {method1();}public static void method1() {lock.lock();try {log.debug("execute method1");method2();} finally {lock.unlock();}}public static void method2() {lock.lock();try {log.debug("execute method2");method3();} finally {lock.unlock();}}public static void method3() {lock.lock();try {log.debug("execute method3");} finally {lock.unlock();}}}【3】中断机制尝试
进行说明:这里面其实是main线程先获得了锁,所以t1线程其实是先进入队列里面,然后在main线程里面将t1设置为了中断 。当main线程释放锁的时候,t1去加锁,发现自己被中断了,所以抛出中断异常,退出加锁 。【其实这个中断加锁,怎么说,就是可以让失去加锁的权利,但是不影响你去排队】
@Slf4jpublic class ReentrantLockDemo {public static void main(String[] args) throws InterruptedException {ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> {log.debug("t1启动...");try {lock.lockInterruptibly();try {log.debug("t1获得了锁");} finally {lock.unlock();}} catch (InterruptedException e) {e.printStackTrace();log.debug("t1等锁的过程中被中断");}}, "t1");lock.lock();try {log.debug("main线程获得了锁");t1.start();//先让线程t1执行Thread.sleep(10000);t1.interrupt();log.debug("线程t1执行中断");} finally {lock.unlock();}}}
经验总结扩展阅读
- Spring 深入——IoC 容器 02
- 五行缺木男和五行缺土女 婚姻不稳需多理解
- 属龙人和属蛇的缘份发展趋势 需多理解包容之心
- 属猴人和属狗感情甜蜜顺利 互相理解则爱情旺
- 饿火命和饿木命合作生意 事业旺盛多理解
- 基于PL022 SPI 控制器 海思3516系列芯片SPI速率慢问题深入分析与优化
- 缺水男适合的配对 相互包容与理解
- 壬水女和癸水男契合度高 互相理解包容
- 深入人心的惊艳签名 文艺且暖心的签名
- 深入剖析Sgementation fault原理