java.util.concurrent包下,有一些关于同步的辅助工具类,比如CountDownLatch、CyclicBarrier等。

CountDownLatch

允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。CountDownLatch允许创建时传入一个初始值,代表门闩的数量,cdl调用await方法进行阻塞;cdl通过countDown()方法拿掉一个门闩,直到门闩的数量变为0时,await阻塞结束。

public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {CountDownLatch cdl = new CountDownLatch(5);for (int i = 0; i < 5; i++) {int finalI = i;new Thread(() -> {try {Thread.sleep(finalI * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "执行完毕");cdl.countDown();}, "线程" + i).start();}cdl.await();System.out.println("所有门闩已经打开,继续执行main线程!");}}

CyclicBarrier

Cyclic 循环的,Barrier 栅栏,屏障。类似满人发车,每凑满20人,才会继续执行,下面是使用示例:

public class CyclicBarrierDemo {public static void main(String[] args) {// runnable 是可选参数,代表达到数量后要执行的代码CyclicBarrier cyclicBarrier = new CyclicBarrier(20, new Runnable() {@Overridepublic void run() {System.out.println("已经20个人了,发车!");}});for (int i = 0; i < 100; i++) {int finalI = i;new Thread(() -> {System.out.println("i:" + finalI);try {cyclicBarrier.await(); // 等待发车,当满20个才会继续执行} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}// 其他业务逻辑}, "线程" + i).start();}}
}

CyclicBarrer 应用于多个线程并发执行,比如网络操作、文件操作同时执行;当所有线程都准备完毕,下面的操作才可进行。

Phaser

阶段执行,jdk7引入。多个线程执行一个任务,此任务分为多个阶段,每个阶段要求全部或者部分线程并发执行并且所有目标线程执行完毕后才可继续执行下一阶段的场景。比如达尔文遗传算法。下面使用Phaser对结婚场景进行模拟,结婚要按照阶段顺序依次执行,先到达、再拜堂、再吃酒席…:

public class PhaserDemo {static MarriagePhaser phaser = new MarriagePhaser();// 定义结婚阶段类static class MarriagePhaser extends Phaser {// 定义每个阶段要执行的任务, 返回值为为true时,代表phaser终止,否则继续执行@Overrideprotected boolean onAdvance(int phase, int registeredParties) {switch (phase) {case 0:System.out.println("所有人都到齐了!共有" + registeredParties + "人");System.out.println();return false;case 1:System.out.println("新郎新娘拜堂!共有" + registeredParties + "人");System.out.println();return false;case 2:System.out.println("所有人酒席吃完了!共有" + registeredParties + "人");System.out.println();return false;case 3:System.out.println("所有人都离开了!共有" + registeredParties + "人");System.out.println();return false;case 4:System.out.println("新郎新娘入洞房!共有" + registeredParties + "人");System.out.println();return true;}return super.onAdvance(phase, registeredParties);}}// 定义人线程static class Person extends Thread {Person (String name) {setName(name);}// 到达现场private void arrive() {System.out.println(getName() + "到达");phaser.arriveAndAwaitAdvance(); // 到达并等待}// 拜堂private void chapel() {if (getName().equals("新郎") || getName().equals("新娘")) {System.out.println(getName() + "拜堂了");phaser.arriveAndAwaitAdvance();} else {phaser.arriveAndDeregister();}}// 酒席private void eat() {if (!getName().equals("新郎") && !getName().equals("新娘")) {phaser.register();}System.out.println(getName() + "吃了");phaser.arriveAndAwaitAdvance();}// 离开private void leave() {System.out.println(getName() + "离开了");phaser.arriveAndAwaitAdvance();}// 洞房private void papapa() {if (getName().equals("新郎") || getName().equals("新娘")) {System.out.println(getName() + "洞房了");phaser.arriveAndAwaitAdvance();}else {phaser.arriveAndDeregister();}}@Overridepublic void run() {arrive();chapel();eat();leave();papapa();}}public static void main(String[] args) {phaser.bulkRegister(7);for(int i=0; i<5; i++) {new Thread(new Person("p" + i)).start();}new Thread(new Person("新郎")).start();new Thread(new Person("新娘")).start();}
}

执行结果如下:

p0到达
新娘到达
新郎到达
p4到达
p3到达
p2到达
p1到达
所有人都到齐了!共有7人新郎拜堂了
p0吃了
p2吃了
p4吃了
新娘拜堂了
p3吃了
p1吃了
新郎新娘拜堂!共有7人新娘吃了
新郎吃了
p3离开了
p0离开了
p1离开了
p4离开了
p2离开了
所有人酒席吃完了!共有7人新娘离开了
新郎离开了
所有人都离开了!共有2人新郎洞房了
新娘洞房了
新郎新娘入洞房!共有2人

Semaphore

Semaphore 是信号量的意思,也成为信号灯(红绿灯),用来保证两个或多个关键代码段不被并发调用;类似锁,但是可以限制并发线程的数量。常用于限流。

public class SemaphoreDemo {public static void main(String[] args) {// 1盏灯,同时只允许一个线程执行Semaphore semaphore = new Semaphore(1);for (int i = 0; i < 3; i++) {int finalI = i;new Thread(() -> {try {semaphore.acquire();System.out.println("T"+ finalI +" run...");Thread.sleep(200);System.out.println("T"+ finalI +" run...");} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}).start();}}
}

Exchanger

交换两个线程的信息(只能是两个线程)。

// 交换线程0与线程1的装备
public class ExchangerDemo {public static void main(String[] args) {Exchanger<String> exchanger = new Exchanger<>();for (int i = 0; i < 2; i++) {new Thread(() -> {try {String threadName = Thread.currentThread().getName();String exchange = exchanger.exchange( threadName + "的装备");System.out.println(threadName + " = " + exchange);} catch (InterruptedException e) {e.printStackTrace();}}, "线程" + i).start();}}}

结果:

线程0 = 线程1的装备
线程1 = 线程0的装备

LockSupport

LockSupport 是比较低级的工具方法,不过使用起来也很方便,相比notify,它可以指定某个thread进行唤醒。

public class LockSupportDemo {public static void main(String[] args) throws InterruptedException {// LockSupport 拥有park与unpark方法,// park的含义为停车,调用此方法的线程将会进入阻塞状态// unpark 则可用于唤醒已经park的线程,此方法可以指定要唤醒的线程,比wait和notify更加灵活Thread t = new Thread(() -> {for (int i = 0; i < 10; i++) {System.out.println("---" + i + "---");if (i == 5) {LockSupport.park();}try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();// 注意,unpark将会将线程的park状态置为unpark// 调用一次后,再次调用park则无法进行线程阻塞// LockSupport.unpark(t);TimeUnit.SECONDS.sleep(8);System.out.println("-------after 8 seconds------");LockSupport.unpark(t); // 需要指定线程}}

JUC: 同步辅助类相关推荐

  1. CountDownLatch,同步辅助类

    public class CountDownLatchextends Object一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 假设定义一个计数器为 5. 每 ...

  2. JUC并发编程之Callable接口、JUC三大辅助类

    目录 8. Callable接口 8.1 创建线程的多种方式 8.2 概述 8.3 用Callable接口创建Thred线程 8.4 小结(重点) 9. JUC 三大辅助类 9.1 概述 9.2 减少 ...

  3. Java中的5种同步辅助类

    当你使用synchronized关键字的时候,是通过互斥器来保障线程安全以及对共享资源的同步访问.线程间也经常需要更进一步的协调执行,来完成复杂的并发任务,比如wait/notify模式就是一种在多线 ...

  4. Java的几个同步辅助类

    Java为我们提供了一些同步辅助类,利用这些辅助类我们可以在多线程编程中,灵活地把握线程的状态. CountDownLatch CountDownLatch一个同步辅助类,在完成一组正在其他线程中执行 ...

  5. Java7并发编程指南——第三章:线程同步辅助类

    Java7并发编程指南--第三章:线程同步辅助类 @(并发和IO流) Java7并发编程指南第三章线程同步辅助类 思维导图 项目代码 思维导图 项目代码 GitHub:Java7Concurrency ...

  6. 各种JUC同步框架的使用

    常用的JUC同步技术主要有以下几个: ReentrantLock 它与synchronized一样,也是可重入锁,可以完全替代synchronized,什么叫可重入,意思就是我锁了一下还可以对同样这把 ...

  7. JUC 高并发编程之JUC三大辅助类

    JUC 高并发编程之JUC三大辅助类 JUC 中提供了三种常用的辅助类,通过这些辅助类可以很好的解决线程数量过 多时 Lock 锁的频繁操作.这三种辅助类为: CountDownLatch: 减少计数 ...

  8. JUC重要辅助类(同步组件及锁)

    一.CountDownLatch(计数器) 原理: CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞.其它线程调用countDown方法会将计数器减1( ...

  9. JUC 三大辅助类解读

    目录 减少计数 CountDownLatch 构造办法 代码实战 循环栅栏 CyclicBarrier 构造器 代码实战 信号灯 Semaphore 构造办法 代码实战 JUC 中提供了三种常用的辅助 ...

最新文章

  1. python使用教程pandas-python学习教程之Numpy和Pandas的使用
  2. Freemarker入门小案例(生成静态网页的其中一种方式)
  3. 下一代Hotmail和MSN Messenger最新界面截图
  4. 华为光猫鉴权解密逆向
  5. 重庆市计算机二级考试大纲,重庆市二级计算机考试大纲.doc
  6. django的动静分离
  7. ROS2学习(九).ROS概念 - ROS 2参数(ROS 2 parameters)
  8. TOTP 介绍及基于 C# 的简单实现
  9. [错误总结]升级spring-boot->2.6.2|hiberate->5.4.33.Final|spring cloud->2021.0.0 |spring admin->2.4.1
  10. 使用pdfviewer预览报错PDF.js v2.9.359 (build: e667c8cbc)信息:file origin does not match viewer‘s
  11. 安装程序遇到错误0x80240037
  12. OpenCV阈值分割
  13. UTM投影坐标计算距离
  14. word插入公式/endnote
  15. mixpanel umeng talkingdata
  16. JS学习之路系列总结五行阵(此文犹如武林之中的易筋经,是你驰骋IT界的武功心法,学会JS五大阵法就学会了JS,博主建议先学三才阵)
  17. python 音乐相册_‎App Store 上的“魔力相册-音乐相册、视频电子相册制作工具”...
  18. PL/SQL 工具远程连接Oracle数据库方法,plsql免安装oracle客户端直接配置oci实战演示
  19. Windows系统的电脑有可以删除的文件夹(个人笔记)
  20. javaSE探赜索隐之二<第二篇博客,磕磕绊绊,收货满满!加油>

热门文章

  1. Unity中基于三角剖分 实现三维城市实时构建
  2. Microsoft Word 远程代码执行漏洞(CVE-2023-21716)
  3. linux yum安装ping,CentOS8 安装ping 命令
  4. 拿不到offer全额退款|第四期人工智能NLP/CV课 培训招生
  5. 新版Microsoft Edge和google chrome谁才是浏览器的王者?
  6. 你本是无意指尖穿堂风,我偏偏心有惊鸿付余生。
  7. 开源面对面系列(S1E03):专访 YiHong,自学成为流行开源项目作者的点滴
  8. 疯狂猜图产品和盈利模式分析
  9. popwndexe.exe程序简介
  10. ios平台alternate icon配置注意事项