概念 代码 demo1 import utils . SleepTools ; import java . util . concurrent . CountDownLatch ; /** * * 案例:ZJJ_JavaBasic_2020/10/19_19:22:55_dg8v8 * 类说明:演示CountDownLatch用法, * 共5个初始化子线程,6个闭锁
概念
代码
demo1
import utils.SleepTools;import java.util.concurrent.CountDownLatch;
/**
*
* 案例:ZJJ_JavaBasic_2020/10/19_19:22:55_dg8v8
* 类说明:演示CountDownLatch用法,
* 共5个初始化子线程,6个闭锁扣除点,扣除完毕后,主线程和业务线程才能继续执行
*/
public class Demo1 {
static CountDownLatch latch = new CountDownLatch(6); //定义初始化CTN计数器是6(6个闭锁扣除点)
/*初始化线程*/
private static class InitThread implements Runnable {
public void run() {
System.out.println("线程_" + Thread.currentThread().getId()
+ " 开始初始化工作......");
latch.countDown();//计数器减一
for (int i = 0; i < 2; i++) {
System.out.println("线程_" + Thread.currentThread().getId()
+ " ........继续做它的工作");
}
}
}
/*业务线程等待latch的计数器为0完成*/
private static class BusiThread implements Runnable {
public void run() {
try {
latch.await(); //等待方法,当这个被唤醒的时候意味着Latch数量被扣减为0了.
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 3; i++) {
System.out.println("业务线程_" + Thread.currentThread().getId()
+ " 开始业务-----");
}
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
SleepTools.ms(1);
System.out.println("线程_" + Thread.currentThread().getId()
+ " 准备好初始化工作步骤1......");
latch.countDown();//扣减
System.out.println("开始步骤2.......");
SleepTools.ms(1);
System.out.println("线程_" + Thread.currentThread().getId()
+ " 准备初始化工作步骤3......");
latch.countDown();//扣减
}
}).start();
new Thread(new BusiThread()).start();
for (int i = 0; i <= 3; i++) {
Thread thread = new Thread(new InitThread());
thread.start();
}
latch.await(); //主线程也可以等待
System.out.println("Main线程开始它的工作了.........");
}
}
控制台打印:
线程_14 开始初始化工作......线程_17 开始初始化工作......
线程_17 ........继续做它的工作
线程_17 ........继续做它的工作
线程_16 开始初始化工作......
线程_15 开始初始化工作......
线程_15 ........继续做它的工作
线程_15 ........继续做它的工作
线程_16 ........继续做它的工作
线程_14 ........继续做它的工作
线程_14 ........继续做它的工作
线程_16 ........继续做它的工作
线程_12 准备好初始化工作步骤1......
开始步骤2.......
线程_12 准备初始化工作步骤3......
Main线程开始它的工作了.........
业务线程_13 开始业务-----
业务线程_13 开始业务-----
业务线程_13 开始业务-----
展现的效果是, 业务线程会在初始化线程全部执行完初始化工作,业务线程才开始进行执行业务代码
demo2
import utils.SleepTools;import java.util.concurrent.CountDownLatch;
/**
*案例:ZJJ_JavaBasic_2020/10/19_19:22:55_dg8v8
*
* boss线程必须等待work线程执行完了, 计数器变为0的时候 boss线程才能开始工作.
*/
public class Demo2 {
static CountDownLatch latch = new CountDownLatch(2);
public static void main(String[] args) {
Thread boss1 = new Thread("boss1") {
public void run() {
System.out.println("[boss线程] 线程开始执行了");
try {
System.out.println("[boss线程] 线程准备阻塞等待子线程完成工作!!!!");
latch.await();
System.out.println("[boss线程] 子线程完成工作了,boss1线程开始唤醒继续工作!!!!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread worker1 = new Thread("worker1") {
public void run() {
System.out.println("work1线程开始执行了");
SleepTools.second(3);
long count = latch.getCount();
System.out.println("当前的计数器 :" + count);
System.out.println("work1线程执行结束,计数器准备减一");
latch.countDown();
}
};
Thread worker2 = new Thread("worker2") {
public void run() {
System.out.println("work2线程开始执行了");
SleepTools.second(3);
long count = latch.getCount();
System.out.println("当前的计数器 :" + count);
System.out.println("work2线程执行结束,计数器准备减一");
latch.countDown();
}
};
boss1.start();
worker1.start();
worker2.start();
}
}
控制台打印的结果:
[boss线程] 线程开始执行了[boss线程] 线程准备阻塞等待子线程完成工作!!!!
work2线程开始执行了
work1线程开始执行了
当前的计数器 :2
work1线程执行结束,计数器准备减一
当前的计数器 :2
work2线程执行结束,计数器准备减一
[boss线程] 子线程完成工作了,boss1线程开始唤醒继续工作!!!!
看控制台打印结果
当boss启动了,发现work线程都还没执行完毕,boss线程此时会被阻塞.
, 当work线程全部执行完毕之后,boss线程就被唤醒,开始工作