多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念及它们之间的关系,本篇是CountDownLatch.
CountDownLatch
简介
CountDownLatch是JDK1.5中引入的,属于线程同步工具.
计数(Count)
CountDownLatch使用时必须指定初始计数,因此只有一个构造方法CountDownLatch(int count)
.这个计数一般是需要参与同步的线程数量.
API
不考虑从父类继承的api,总共只有5个api:
-
await(): 阻塞线程,直到计数(Count)减为0以后释放(release)线程.
-
await(long timeout, TimeUnit unit): 阻塞指定的时间,到时侯不管计数是否为0都要释放
-
countDown(): 使计数减1.
-
getCount()
-
toString()
适用场景
一个线程(或者多个)等待另外一组线程完成某种操作以后才能执行.
案例
案例简介
主线程发布开始命令以后10个工作线程开始工作,同时主线程阻塞,需要等待10个工作线程完成工作以后继续执行
案例代码
主要分为2个类,Worker.java和WorkerTest.java.
Worker.java代码如下:
package com.ms.thread.CountDownLatch;
import java.util.concurrent.CountDownLatch;
/**
* @author chenxin
* @since 2018-04-20
*/
public class Worker implements Runnable{
//用于控制工作线程开始
private CountDownLatch startLatch;
//用于控制主线程开始
private CountDownLatch doneLatch;
public Worker(CountDownLatch startCdl,CountDownLatch doneCdl) {
this.startLatch = startCdl;
this.doneLatch = doneCdl;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+":等待发布工作命令");
//等待主线程发布开始命令
startLatch.await();
//主线程发布命令以后开始做工作,睡眠的目的是防止工作线程的“xxx完成工作”比主线程的“发布工作命令”先打印
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+":完成工作");
//做完工作以后通知CountDownLatch已完成工作,将计数减1
doneLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
WorkerTest.java代码如下:
package com.ms.thread.CountDownLatch;
import java.util.concurrent.CountDownLatch;
/**
* 测试Worker类
* @author chenxin
* @since 2018-04-20
*/
public class WorkerTest {
//工作线程数量
private static int workerNum = 10;
public static void main(String[] args) {
//控制多个工作线程等待主线程
CountDownLatch startCdl = new CountDownLatch(1);
//控制主线程等待多个工作线程
CountDownLatch doneCdl = new CountDownLatch(workerNum);
for(int i=0; i<workerNum; i++) {
new Thread(new Worker(startCdl, doneCdl), "worker-"+i).start();
}
//主线程发出开始工作命令
startCdl.countDown();
System.out.println("=== 主线程发布工作命令 ===");
//主线程等待工作线程结束
try {
doneCdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("=== 完成全部工作 ===");
}
}
案例执行结果
打印的结果如下:
worker-0:等待发布工作命令
worker-6:等待发布工作命令
worker-5:等待发布工作命令
worker-4:等待发布工作命令
worker-3:等待发布工作命令
worker-1:等待发布工作命令
worker-2:等待发布工作命令
worker-9:等待发布工作命令
worker-8:等待发布工作命令
worker-7:等待发布工作命令
=== 主线程发布工作命令 ===
worker-1:完成工作
worker-6:完成工作
worker-4:完成工作
worker-5:完成工作
worker-7:完成工作
worker-2:完成工作
worker-8:完成工作
worker-9:完成工作
worker-0:完成工作
worker-3:完成工作
=== 完成全部工作 ===
网友评论