当前位置: 首页 > news >正文

线程协作工具类【CountDownLatch倒数门闩、Semaphore信号量、CyclicBarrier循环栏栅、Condition接口】

线程协作工具类

  • CountDownLatch倒数门闩
  • Semaphore信号量
  • CyclicBarrier循环栅栏
    • CyclicBarrier和CountDownLatch区别:
  • Condition接口(条件对象)

转自 极客时间

线程协作工具类就是帮助程序员更容易的让线程之间进行协作,来完成某个业务功能。

在这里插入图片描述

CountDownLatch倒数门闩

在这里插入图片描述


import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/*** CountDownLatch案例:6个程序猿加班* 当计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行*/
public class Demo11CountDownLatch {public static void main(String[] args) throws InterruptedException {//计数门闩CountDownLatch countDownLatch = new CountDownLatch(6);for (int i = 1; i <= 6; i++) {new Thread(()->{try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace(); }System.out.println(Thread.currentThread().getName() + "\t上完班,离开公司");countDownLatch.countDown();}, String.valueOf(i)).start();}new Thread(()->{try {countDownLatch.await();System.out.println(Thread.currentThread().getName()+"\t卷王最后关灯走人");} catch (InterruptedException e) {e.printStackTrace();}}, "7").start();}
}

Semaphore信号量

在这里插入图片描述

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;/*** Semaphore案例:三辆小汽车抢车位* Semaphore信号量主要作用:1.用于多个共享资源的互斥使用,2.用于并发线程数的控制*/
public class Demo12Semaphore {public static void main(String[] args) {//模拟资源类,有3个空车位Semaphore semaphore = new Semaphore(3);for (int i = 1; i <= 6; i++) {new Thread(()->{try{//占有资源semaphore.acquire();System.out.println(Thread.currentThread().getName()+"\t抢到车位");try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace(); }System.out.println(Thread.currentThread().getName()+"\t停车3秒后离开车位");} catch (Exception e) {e.printStackTrace();} finally {//释放资源semaphore.release();}}, "Thread-Car-"+String.valueOf(i)).start();}}
}

CyclicBarrier循环栅栏

在这里插入图片描述

import java.util.concurrent.CyclicBarrier;/*** 案例:集齐7龙珠召唤神龙*/
public class Demo13CyclicBarrier {public static void main(String[] args) {CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{System.out.println("======召唤神龙");});for (int i = 1; i <= 14; i++) {final int tempInt = i;new Thread(()->{try {System.out.println(Thread.currentThread().getName() + "\t收集到第" + tempInt + "颗龙珠");cyclicBarrier.await();System.out.println(Thread.currentThread().getName() + "\t第" + tempInt + "颗龙珠飞走了");} catch (Exception e) {e.printStackTrace();}}, "Thread-"+String.valueOf(i)).start();}}
}

CyclicBarrier和CountDownLatch区别:

在这里插入图片描述

Condition接口(条件对象)

在这里插入图片描述

import java.util.Collections;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 案例:Tony仨小哥洗剪吹* 演示多线程之间按顺序调用,实现A->B->C* 三个线程Tony要求如下:*   tony雄雄-洗头,tony超超-理发,tony麦麦-吹干*   。。。*   tony雄雄-洗头,tony超超-理发,tony麦麦-吹干*  依次来10轮*/
public class Demo14ConditionDemo {public static void main(String[] args) {ShareData shareData = new ShareData();new Thread(()->{for (int i = 0; i < 10; i++) {shareData.wash();}}, "tony-雄雄").start();new Thread(()->{for (int i = 0; i < 10; i++) {shareData.cut();}}, "tony-超超").start();new Thread(()->{for (int i = 0; i < 10; i++) {shareData.cook();}}, "tony-麦麦").start();}
}
class ShareData {private volatile int number = 1; //tony-雄雄:1, tony-超超:2, tony-麦麦:3private Lock lock = new ReentrantLock();private Condition c1 = lock.newCondition(); //number == 1private Condition c2 = lock.newCondition(); //number == 2private Condition c3 = lock.newCondition(); //number == 3/*** A线程每一轮要执行的操作*/public void wash() {lock.lock();try{//判断while(number != 1){c1.await();//阻塞}//模拟线程执行的任务System.out.println(Thread.currentThread().getName()+"-洗头");//通知number = 2;c2.signal();//唤醒了超超} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}/*** B线程每一轮要执行的操作*/public void cut() {lock.lock();try{//判断while(number != 2){c2.await();//阻塞}//模拟线程执行的任务System.out.println(Thread.currentThread().getName()+"-理发");//通知number = 3;c3.signal();//唤醒3} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void cook() {lock.lock();try{//判断while(number != 3){c3.await();}//模拟线程执行的任务System.out.println(Thread.currentThread().getName()+"-吹干");//通知number = 1;c1.signal();//唤醒雄雄} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}
http://www.lryc.cn/news/295148.html

相关文章:

  • Python 函数式编程进阶:map、filter、reduce
  • 大模型|基础_word2vec
  • 14.2 url后端过滤器(❤❤)
  • Leetcode 377 组合总和 Ⅳ
  • CleanMyMacX4.14.6如何清理mac垃圾内存
  • Java 学习和实践笔记(1)
  • 【自然语言处理-工具篇】spaCy<1>--介绍及安装指南
  • LeetCode树总结
  • AI专题:冬渐去、春将来,待看,AI 开花,数据挂果,可控链潮起
  • Netty源码系列 之 EventLoop run()方法 源码
  • ChatGPT 4.0 升级指南, ChatGPT Plus(GPT 4.0) 有何优势?
  • springboot157基于springboot的线上辅导班系统的开发与设计
  • 【机器学习】机器学习简单入门
  • 考研数据结构笔记(1)
  • 【深度学习理论】持续更新
  • npm ERR! reason: certificate has expired(淘宝镜像过期)
  • “极简壁纸“爬虫JS逆向·实战
  • Django通过Json配置文件分配多个定时任务
  • C++ 搜索二叉树的删除
  • 构建中国人自己的私人GPT—支持中文
  • elementui 回到顶部报错
  • go-carbon v2.3.8 发布,轻量级、语义化、对开发者友好的 golang 时间处理库
  • 【详解】斗地主随机发牌项目
  • 多账号运营为什么要使用动态住宅代理IP?
  • [C++] 如何使用Visual Studio 2022 + QT6创建桌面应用
  • Arduino 推出基于乐鑫 ESP32-S3 的 STEM 教育机器人
  • Blender使用Rigify和Game Rig Tool基础
  • 【Unity优化(一)】音频优化
  • 算法.1-三大排序算法-对数器-二分
  • Midjourney新功能介绍:风格参考(Style References)详解