假设一场短跑比赛,使用多个线程代表每个运动员的状态和比赛过程,需要每个运动员同时出发,打印出每个关键节点的时间作为参考:
CountDownLatch
所有方法
| Modifier and Type | Method and Description |
|---|---|
void | await()导致当前线程等到锁存器计数到零,除非线程是 interrupted 。 |
boolean | await(long timeout, TimeUnit unit)使当前线程等待直到锁存器计数到零为止,除非线程为 interrupted或指定的等待时间过去。 |
void | countDown()减少锁存器的计数,如果计数达到零,释放所有等待的线程。 |
long | getCount()返回当前计数。 |
String | toString()返回一个标识此锁存器的字符串及其状态。 |
package com.muyi;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
/**
* @Author: muyi
* @Date: 2021/3/23 10:27
*/
public class Main {
final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws InterruptedException
{
CountDownLatch startLatch = new CountDownLatch(1);//控制比赛协作
CountDownLatch endLatch = new CountDownLatch(8);// 每个人的比赛进程
Runner run1 = new Runner(1,startLatch, endLatch);
Runner run2 = new Runner(2, startLatch,endLatch);
Runner run3 = new Runner(3, startLatch,endLatch);
Runner run4 = new Runner(4, startLatch,endLatch);
Runner run5 = new Runner(5, startLatch,endLatch);
Runner run6 = new Runner(6, startLatch,endLatch);
Runner run7 = new Runner(7, startLatch,endLatch);
Runner run8 = new Runner(8, startLatch,endLatch);
run1.start();
run2.start();
run3.start();
run4.start();
run5.start();
run6.start();
run7.start();
run8.start();
System.out.println("3秒钟预备!");
Thread.sleep(3000);
System.out.println("起跑!"+sdf.format(new Date()));
startLatch.countDown(); //工作开始
endLatch.await();// 等待所有工人完成工作
System.out.println("比赛完成 " + sdf.format(new Date()));
}
static class Runner extends Thread {
int no;
CountDownLatch startLatch;
CountDownLatch endLatch;
public Runner(int no, CountDownLatch startLatch,CountDownLatch endLatch) {
this.no = no;
this.startLatch=startLatch;
this.endLatch = endLatch;
}
@Override
public void run() {
try {
Random random = new Random(no);
Integer runTime = random.nextInt(5000)*2;
System.out.println("run "+no+"进入赛道,等待开始!预计用时:"+runTime+"ms");
startLatch.await(); //等待开始工作时间
System.out.println("run " + no + " 起跑时间 "+ sdf.format(new Date()));
Thread.sleep(runTime);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("run " + no + " 到达终点时间 " + sdf.format(new Date())+";剩余完成比赛人:"+(endLatch.getCount()-1));
// if(no == 1) { // code1
endLatch.countDown();// 完成比赛,计数器减一
// }
}
}
}
}
// out
3秒钟预备!
run 5进入赛道,等待开始!预计用时:8974ms
run 1进入赛道,等待开始!预计用时:7970ms
run 8进入赛道,等待开始!预计用时:4728ms
run 7进入赛道,等待开始!预计用时:8472ms
run 4进入赛道,等待开始!预计用时:3724ms
run 2进入赛道,等待开始!预计用时:2216ms
run 3进入赛道,等待开始!预计用时:7468ms
run 6进入赛道,等待开始!预计用时:3222ms
起跑!2021-04-14 14:58:01
run 5 起跑时间 2021-04-14 14:58:01
run 1 起跑时间 2021-04-14 14:58:01
run 8 起跑时间 2021-04-14 14:58:01
run 4 起跑时间 2021-04-14 14:58:01
run 7 起跑时间 2021-04-14 14:58:01
run 3 起跑时间 2021-04-14 14:58:01
run 6 起跑时间 2021-04-14 14:58:01
run 2 起跑时间 2021-04-14 14:58:01
run 2 到达终点时间 2021-04-14 14:58:03;剩余完成比赛人:7
run 6 到达终点时间 2021-04-14 14:58:04;剩余完成比赛人:6
run 4 到达终点时间 2021-04-14 14:58:05;剩余完成比赛人:5
run 8 到达终点时间 2021-04-14 14:58:06;剩余完成比赛人:4
run 3 到达终点时间 2021-04-14 14:58:08;剩余完成比赛人:3
run 1 到达终点时间 2021-04-14 14:58:09;剩余完成比赛人:2
run 7 到达终点时间 2021-04-14 14:58:09;剩余完成比赛人:1
run 5 到达终点时间 2021-04-14 14:58:10;剩余完成比赛人:0
比赛完成 2021-04-14 14:58:10
通过上面的输入结果得到:所有人同时起步,且详细记录了比赛结束的时间;
如果放开注释code1,发现比赛无法结束,因为只有run1正式通知了裁判组完成了比赛(endLatch.countDown());
3秒钟预备!
run 7进入赛道,等待开始!预计用时:8472ms
run 8进入赛道,等待开始!预计用时:4728ms
run 5进入赛道,等待开始!预计用时:8974ms
run 4进入赛道,等待开始!预计用时:3724ms
run 2进入赛道,等待开始!预计用时:2216ms
run 6进入赛道,等待开始!预计用时:3222ms
run 1进入赛道,等待开始!预计用时:7970ms
run 3进入赛道,等待开始!预计用时:7468ms
起跑!2021-04-14 14:59:10
run 8 起跑时间 2021-04-14 14:59:10
run 5 起跑时间 2021-04-14 14:59:10
run 7 起跑时间 2021-04-14 14:59:10
run 4 起跑时间 2021-04-14 14:59:10
run 2 起跑时间 2021-04-14 14:59:10
run 3 起跑时间 2021-04-14 14:59:10
run 1 起跑时间 2021-04-14 14:59:10
run 6 起跑时间 2021-04-14 14:59:10
run 2 到达终点时间 2021-04-14 14:59:12;剩余完成比赛人:7
run 6 到达终点时间 2021-04-14 14:59:13;剩余完成比赛人:7
run 4 到达终点时间 2021-04-14 14:59:13;剩余完成比赛人:7
run 8 到达终点时间 2021-04-14 14:59:14;剩余完成比赛人:7
run 3 到达终点时间 2021-04-14 14:59:17;剩余完成比赛人:7
run 1 到达终点时间 2021-04-14 14:59:18;剩余完成比赛人:7
run 7 到达终点时间 2021-04-14 14:59:18;剩余完成比赛人:6
run 5 到达终点时间 2021-04-14 14:59:19;剩余完成比赛人:6
CyclicBarrier

所有方法
int | await()等待所有 parties已经在这个障碍上调用了 await 。 |
|---|---|
int | await(long timeout, TimeUnit unit)等待所有 parties已经在此屏障上调用 await ,或指定的等待时间过去。 |
int | getNumberWaiting()返回目前正在等待障碍的各方的数量。 |
int | getParties()返回旅行这个障碍所需的聚会数量。 |
boolean | isBroken()查询这个障碍是否处于破碎状态。 |
void | reset()将屏障重置为初始状态。 |
CyclicBarrier有两个构造方法:
CyclicBarrier(int parties)
创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待它时,它将跳闸,并且当屏障跳闸时不执行预定义的动作。
package com.muyi;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
/**
* @Author: muyi
* @Date: 2021/3/23 10:27
*/
public class Main {
final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws InterruptedException
{
CyclicBarrier cyclicBarrier = new CyclicBarrier(8);
Runner run1 = new Runner(1, cyclicBarrier);
Runner run2 = new Runner(2, cyclicBarrier);
Runner run3 = new Runner(3, cyclicBarrier);
Runner run4 = new Runner(4, cyclicBarrier);
Runner run5 = new Runner(5, cyclicBarrier);
Runner run6 = new Runner(6, cyclicBarrier);
Runner run7 = new Runner(7, cyclicBarrier);
Runner run8 = new Runner(8, cyclicBarrier);
run1.start();
run2.start();
run3.start();
run4.start();
run5.start();
run6.start();
run7.start();
run8.start();
}
static class Runner extends Thread {
int no;
CyclicBarrier cyclicBarrier;
public Runner(int no, CyclicBarrier cyclicBarrier) {
this.no = no;
this.cyclicBarrier=cyclicBarrier;
}
@Override
public void run() {
try {
Random random = new Random(no);
Integer runTime = random.nextInt(5000)*2;
Thread.sleep(runTime/10);// 放大线程准备时间
System.out.println("run "+no+"进入赛道,等待开始!预计用时:"+runTime+"ms,准备完成人数:"+(cyclicBarrier.getNumberWaiting()+1));
cyclicBarrier.await();
System.out.println("run " + no + " 起跑时间 "+ sdf.format(new Date()));
Thread.sleep(runTime);
System.out.println("run " + no + " 预计到达终点时间 " + sdf.format(new Date())+";完成比赛人数:"+(cyclicBarrier.getNumberWaiting()+1));
cyclicBarrier.await();
System.out.println("全部完成 " + sdf.format(new Date()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// out
run 2进入赛道,等待开始!预计用时:2216ms,准备完成人数:1
run 6进入赛道,等待开始!预计用时:3222ms,准备完成人数:2
run 4进入赛道,等待开始!预计用时:3724ms,准备完成人数:3
run 8进入赛道,等待开始!预计用时:4728ms,准备完成人数:4
run 3进入赛道,等待开始!预计用时:7468ms,准备完成人数:5
run 1进入赛道,等待开始!预计用时:7970ms,准备完成人数:6
run 7进入赛道,等待开始!预计用时:8472ms,准备完成人数:7
run 5进入赛道,等待开始!预计用时:8974ms,准备完成人数:8
run 1 起跑时间 2021-04-14 14:53:31
run 2 起跑时间 2021-04-14 14:53:31
run 4 起跑时间 2021-04-14 14:53:31
run 3 起跑时间 2021-04-14 14:53:31
run 8 起跑时间 2021-04-14 14:53:31
run 5 起跑时间 2021-04-14 14:53:31
run 7 起跑时间 2021-04-14 14:53:31
run 6 起跑时间 2021-04-14 14:53:31
run 2 预计到达终点时间 2021-04-14 14:53:33;完成比赛人数:1
run 6 预计到达终点时间 2021-04-14 14:53:34;完成比赛人数:2
run 4 预计到达终点时间 2021-04-14 14:53:34;完成比赛人数:3
run 8 预计到达终点时间 2021-04-14 14:53:35;完成比赛人数:4
run 3 预计到达终点时间 2021-04-14 14:53:38;完成比赛人数:5
run 1 预计到达终点时间 2021-04-14 14:53:39;完成比赛人数:6
run 7 预计到达终点时间 2021-04-14 14:53:39;完成比赛人数:7
run 5 预计到达终点时间 2021-04-14 14:53:40;完成比赛人数:8
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
全部完成 2021-04-14 14:53:40
Process finished with exit code 0
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行。
package com.muyi;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
/**
* @Author: muyi
* @Date: 2021/3/23 10:27
*/
public class Main {
final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws InterruptedException
{
CyclicBarrier cyclicBarrier = new CyclicBarrier(8,new Runnable(){
@Override
public void run() {
System.out.println("********裁判组记录,发令***********");
System.out.println(sdf.format(new Date()));
}
});
Runner run1 = new Runner(1, cyclicBarrier);
Runner run2 = new Runner(2, cyclicBarrier);
Runner run3 = new Runner(3, cyclicBarrier);
Runner run4 = new Runner(4, cyclicBarrier);
Runner run5 = new Runner(5, cyclicBarrier);
Runner run6 = new Runner(6, cyclicBarrier);
Runner run7 = new Runner(7, cyclicBarrier);
Runner run8 = new Runner(8, cyclicBarrier);
run1.start();
run2.start();
run3.start();
run4.start();
run5.start();
run6.start();
run7.start();
run8.start();
}
static class Runner extends Thread {
int no;
CyclicBarrier cyclicBarrier;
public Runner(int no, CyclicBarrier cyclicBarrier) {
this.no = no;
this.cyclicBarrier=cyclicBarrier;
}
@Override
public void run() {
try {
Random random = new Random(no);
Integer runTime = random.nextInt(5000)*2;
Thread.sleep(runTime/10);// 放大线程准备时间
System.out.println("run "+no+"进入赛道,等待开始!预计用时:"+runTime+"ms,准备完成人数:"+(cyclicBarrier.getNumberWaiting()+1));
cyclicBarrier.await();
System.out.println("run " + no + " 起跑时间 "+ sdf.format(new Date()));
Thread.sleep(runTime);
System.out.println("run " + no + " 预计到达终点时间 " + sdf.format(new Date())+";完成比赛人数:"+(cyclicBarrier.getNumberWaiting()+1));
cyclicBarrier.await();
System.out.println("全部完成 " + sdf.format(new Date()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//out
run 2进入赛道,等待开始!预计用时:2216ms,准备完成人数:1
run 6进入赛道,等待开始!预计用时:3222ms,准备完成人数:2
run 4进入赛道,等待开始!预计用时:3724ms,准备完成人数:3
run 8进入赛道,等待开始!预计用时:4728ms,准备完成人数:4
run 3进入赛道,等待开始!预计用时:7468ms,准备完成人数:5
run 1进入赛道,等待开始!预计用时:7970ms,准备完成人数:6
run 7进入赛道,等待开始!预计用时:8472ms,准备完成人数:7
run 5进入赛道,等待开始!预计用时:8974ms,准备完成人数:8
********裁判组记录,发令***********
2021-04-14 14:55:54
run 5 起跑时间 2021-04-14 14:55:54
run 2 起跑时间 2021-04-14 14:55:54
run 4 起跑时间 2021-04-14 14:55:54
run 3 起跑时间 2021-04-14 14:55:54
run 7 起跑时间 2021-04-14 14:55:54
run 6 起跑时间 2021-04-14 14:55:54
run 1 起跑时间 2021-04-14 14:55:54
run 8 起跑时间 2021-04-14 14:55:54
run 2 预计到达终点时间 2021-04-14 14:55:56;完成比赛人数:1
run 6 预计到达终点时间 2021-04-14 14:55:57;完成比赛人数:2
run 4 预计到达终点时间 2021-04-14 14:55:58;完成比赛人数:3
run 8 预计到达终点时间 2021-04-14 14:55:59;完成比赛人数:4
run 3 预计到达终点时间 2021-04-14 14:56:02;完成比赛人数:5
run 1 预计到达终点时间 2021-04-14 14:56:02;完成比赛人数:6
run 7 预计到达终点时间 2021-04-14 14:56:03;完成比赛人数:7
run 5 预计到达终点时间 2021-04-14 14:56:03;完成比赛人数:8
********裁判组记录,发令***********
2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
全部完成 2021-04-14 14:56:03
版权声明:本文为qq_37206616原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
