admin管理员组文章数量:1599448
package com.lezu.springboot.controller;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* ReentrantLock中Condition的使用
* PrintA、PrintB、PrintC三个方法
* 运行顺序为 PrintA -> PrintB -> PrintC 这个时候可以使用到ReentrantLock配和Condition来使用
* 举例场景:下单(订单表)-->支付(支付表)-->发送通知短信-->物流-->完成交易发放积分
*/
public class ConditionTest {
public static void main(String[] args) {
Data3 date = new Data3();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
date.PrintA();
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
date.PrintB();
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
date.PrintC();
}
}, "C").start();
}
}
/**
* 当number==1的时候运行PrintA
* 当number==2的时候运行PrintB
* 当number==3的时候运行PrintC
*/
class Data3 {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int number = 1;
public void PrintA() {
lock.lock();
try {
while (number == 1) {
//唤醒PrintB
System.out.println(Thread.currentThread().getName() + "==>AAA");
number = 2;
condition2.signal();
}
//PrintA等待
condition1.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void PrintB() {
lock.lock();
try {
while (number == 2) {
//唤醒PrintC
System.out.println(Thread.currentThread().getName() + "==>BBB");
number = 3;
condition3.signal();
}
//PrintB等待
condition2.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void PrintC() {
lock.lock();
try {
while (number == 3) {
//唤醒PrintA
System.out.println(Thread.currentThread().getName() + "==>CCC");
number = 1;
condition1.signal();
}
//PrintC等待
condition3.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
运行结果
补充 ReentrantLock和synchronized的区别:
1.使用区别
1、Lock是一个接口,而synchronized是关键字,是JVM内置的语言实现。
2、Synchronized发生异常时,会自动释放线程占用的锁,不会发生死锁现象。Lock发生异常时,若没有主动释放,极有可能造成死锁,需要在finally中调用unlock()方法释放锁。
3、Lock有着显式的操作过程,开发人员必须手动指定何时加锁,何时释放锁,因而重入锁对逻辑控制的灵活性优于synchronized。
4、一个ReentrantLock可以绑定多个Condition对象,仅需多次调用new Condition()即可。而在synchronized中锁对象的wait()、notify()/notifyAll()可以实现一个隐含的条件,如果要和多余的条件关联,就不得不使用多个锁。
性能比较
JDK5中,重入锁的性能是远优于synchronized的。因为这是一个重量级操作,对性能的最大的影响是阻塞的实现,挂起线程和恢复线程的操作,都需要转入内核态中完成,给并发带来很大的压力。
但从JDK6开始,synchronized中加入了自适应自旋、锁消除、锁粗化、轻量级锁、偏向锁等一系列优化之后,两者的性能差距不大了。
本文标签: LockReentrantLockcondition
版权声明:本文标题:Lock锁中ReentrantLock中Condition的使用 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728321834a1153925.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论