【多线程开发 5】实践使用Lock和Condition
创始人
2024-11-14 20:34:06
0

Lock和Condition

Lock

线程之间同步或者竞争都需要锁这类结构,一般我们都会用Object的wait和signal搭配synchronized关键字进行多线程开发,但是很多时候会造成死锁的现象,这是因为synchroniezd无法破坏死锁的产生条件,但是Lock接口的一些实现类可以帮助我们避免思索地产生。一般用的比较多的是ReentrantLock这个Lock接口的实现类。

ReentrantLock

很多时候ReentrantLock是为了替代synchronized情况下同意出现死锁的情况的。并且相比于synchroniezd还有以下几个优点

  • 可中断
  • 可以设置超时时间
  • 可以设置为公平锁
  • 支持多个条件变量
  • 与 synchronized 一样,都支持可重入

比如笔者有使用过一些任务分配和执行工具,如果出现了一台机器/CPU出现了同一时间内分配了多个任务或者长时间没有分配任务,那么对于我们的业务来说就很危险,在这种情况下可以通过使用ReentrantLock帮助我们解决这种问题

    public static void main(String[] args) throws ExecutionException, InterruptedException {         /**          * 我们是以任务为主体获取信息,如果是我们的资源主体拉取信息,则reentrantLock是可以工具是否是公平锁而且获得对资源的掌控权的          * 如果是tryLock()方法,则只要一看到有所就会获取锁          */ ​         /**          * 资源有10个          */         AtomicReference resource = new AtomicReference<>(10);         //锁         final Lock reentrantLock = new ReentrantLock(); ​         ExecutorService executorService = Executors.newFixedThreadPool(1); ​         List taskInfos = new ArrayList<>();         for (int i = 0; i < 10; i++) {             taskInfos.add(new TaskInfo().setTaskName("任务" + i).setId(1));         } ​         List> taskList = new ArrayList<>();         List didntExecuteTaskList = new ArrayList<>();         for (int i = 0; i < 100; i++) {             int finalI = i;             taskList.add(CompletableFuture.supplyAsync(() -> {                 reentrantLock.lock();                 TaskInfo taskInfo = taskInfos.get(finalI % 10).setId(finalI);                 boolean executable = resource.get() > 0;                 if (executable) {                     resource.getAndSet(resource.get() - 1);                     /**                      * 开始执行                      */                     CompletableFuture.supplyAsync(() -> {                         try {                             Thread.sleep((long) (Math.random() * 100 % 2));                         } catch (InterruptedException e) {                             throw new RuntimeException(e);                         }                         /**                          * 执行完成                          */                         resource.getAndSet(resource.get() + 1);                         return 1;                     });                     reentrantLock.unlock();                 } else {                     didntExecuteTaskList.add(taskInfo);                 }                 return "任务" + taskInfo.getTaskName() + "执行" + (executable ? "成功" : "失败");             }, executorService));         } ​         for (CompletableFuture completableFuture : taskList) {             System.out.println(completableFuture.get());         }         System.out.println("没有完成的任务有" + didntExecuteTaskList.stream().map(TaskInfo::getTaskName).collect(Collectors.toList()));     } 

此时有可能会发生死锁,如果出现一些任务长时间占用,那么我们可以通过ReentrantLock 的 lockInterruptibly() 方法及时进行打断,这种方式在synchronized情况下无法实现

Condition

Condition将Object监控器方法( wait , notify和notifyAll )分解为不同的对象,从而通过与任意Lock实现结合使用,从而使每个对象具有多个等待集。 Lock替换了synchronized方法和语句的使用,而Condition替换了Object监视器方法的使用。

Condition实例从本质上绑定到锁。 要获取特定Lock实例的Condition实例,请使用其newCondition()方法

如果说Lock是锁,只有拿到锁才能执行的话,Condition就是信号量,有了信号量才能执行后续的操作,Condition更像是线程之间的同步机制,如果说有多个线程之间需要相互进行条件制约的话,可以通过Condition进行开发业务。

有时候lock抢到了锁,可能发现不需要进行执行,所以的话还需要condition做更加细致的操作。

比如在Lock和Condition下实现的消息队列中,Lock保证消息队列线程安全,Condition保证业务需要,比如说不能消费空队列,或者往满队列中添加信息,这种方式在很多框架中都有使用

相关内容

热门资讯

四分钟经验!微信小程序破解内购... 四分钟经验!微信小程序破解内购,新西游辅助器(辅助)确实是有脚本(哔哩哔哩)1)微信小程序破解内购免...
第一分钟手册!欢乐达人透视脚本... 第一分钟手册!欢乐达人透视脚本,超级三加一辅助软件(辅助)一直真的有app(哔哩哔哩)1、许多玩家不...
第7分钟策略!杭州都莱辅助软件... 第7分钟策略!杭州都莱辅助软件有没有用,方片十三张外卦(辅助)一直存在有app(哔哩哔哩)1、完成杭...
九分钟练习!约局八辅助器,海螺... 九分钟练习!约局八辅助器,海螺众娱辅助(辅助)原来真的是有辅助器(哔哩哔哩)约局八辅助器透视方法中分...
四分钟绝活!微信小程序边锋干橙... 四分钟绝活!微信小程序边锋干橙眼辅助,超级三加一正版(辅助)果然存在有app(哔哩哔哩)1、操作简单...
第九分钟课程!微信卡农辅助,新... 第九分钟课程!微信卡农辅助,新九游辅助器软件激活码(辅助)果然真的是有软件(哔哩哔哩)一、新九游辅助...
两分钟手筋!新道游科技透视收费... 两分钟手筋!新道游科技透视收费,财神十三张脚本效果图(辅助)一贯有挂下载(哔哩哔哩)1、不需要AI权...
七分钟法子!情怀游戏辅助器,九... 七分钟法子!情怀游戏辅助器,九游破解辅助插件教程(辅助)一贯是有辅助器(哔哩哔哩);1、七分钟法子!...
2分钟总结!杭州都莱挂,九游破... 2分钟总结!杭州都莱挂,九游破解版真的假的(辅助)切实真的是有插件(哔哩哔哩)1、九游破解版真的假的...
四分钟诀窍!四川麻将血战如何开... 四分钟诀窍!四川麻将血战如何开挂辅助,财神十三章安装包(辅助)真是真的是有app(哔哩哔哩)1、这是...