这是我参与更文应战的第 6 天,活动概略查看: 更文应战

1. CountDownLatch 简介

在上篇中咱们介绍了 CyclicBarrier 类的运用,经过 CyclicBarrier 咱们能够结束一些分批实施汇总的任源码编辑器务,线程池创立的四种变量名的命名规矩此次介绍的 CountDownLatch 则是结束相似“倒源码本钱计时”的功用。

2. CountDownLatch 简略线程池使用

CountDownLatch 源码很简线程池原理练,它供给两个典型的办法来结束“倒计时功用”。CountDownLatch 在结构办法中指定门闩锁 latch 的个数,当 latch 的个数为 0 的时分则唤醒悉数等候状况下的线程。它供给了以下几个要害办法:

  • c源码ountDown():经过调用 countDown 办法结束门闩锁 -1 的作用。
  • await():让当时线程进入等候。
  • getCount():获取门闩锁的个数。

下面咱们经过一个示例代码来看一线程池原理下:

public class MyTest {
static CountD变量与函数ownLa源码本钱tch countD变量名ownLatch;线程池
public static void main(String[]args){
countDownLatch = new CountD变量名的命名规矩ownLatch(3);
for(int i=0;i<3;i++){
new Thread(new Runnab线程池面试le() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "--抵达线程池创立的四种车门");
System.out.println(Thread.currentThread().getName() + "--已登车");
countDownLatch.countDown();
}
}).star变量与函数t();
}
try {
countDownLatch.await();
} catch (线程池InterruptedException e) {
e.printStackTrace();
}
System.线程池面试题out.println(Thread.currentThread().getName() + "--登车结束");
}
}

在示例代码中,经过结构函数创立一个指定 latch 个数为 3CountDownLatch 的办法,一同创立了三个线程,在每个线程的内部分别调用一次 countDown() 办法,终究在主线程中调用await 办法进行等候堵塞,终究结束输出。
实施效果:

Thread-0--抵源码年代达车门
Thread-1--抵达车门
Thread-0--已登车
Thread-1--已登车
Thread-2变量的界说--抵达车门
Thread-2--已登车
main--登车结束

变量的界说上面能够得知 CountDownLatch 以下特点:

  1. 线线程池程中实施 countDown线程池面试题 办法后能继续实施后续代码,线程不会堵塞等候;
  2. latch 个数为 0 的时分会当即唤醒 await 等候的线程;

3. CountDownLatch 源码解析

结合上面临 CountDownLatch 功用的描绘,线程是什么意思假定源码本钱让咱们结束一个这样的功用,咱们首要想到的思路源码交易网站源码应该是在东西类中坚持一个 Co变量泵unt 计数变量,然后坚持对该变量的判别。那么咱们来看看CountDownLatch 是怎样结束的。线程池

public class CountDownLatch {
/**
* Synchroni变量类型有哪些zation control For CountDownLatch线程和进程的差异是什么.
*源码分享网 Uses AQS state to represent count.
*/
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVer变量名sionUID = 4982264981922014374L;
Sync(int count)源码本钱 {
setSta变量值te(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ?线程池面试题 1 : -1;
}变量的指针其意义是指该变量的
protected boolean tryReleaseShared(int releases) {
// Decrem线程是什么意思ent count; sig变量的指针其意义是指该变量的nal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
private final Sync源码 sync;
public CountDownLatch(int count) {
if (count < 0) throw new IllegalA线程池的七个参数rgumentEx变量泵ception("count < 0");
this.sync = new Sync(count);
}
/**
* 让当时线程进行等候,直线程池面试题到锁个数为0或许当时线程interrupt
*	假定当时锁latch个数为0,则当即源码之家回来
*/
pu变量英文blic void awai源码编辑器编程猫下载t() throws Interrupte线程dException {
sync.acquireSharedInterruptibly(1);
}
pu源码本钱blic boolean await(long t变量类型有哪些imeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
/**
* 减少latch锁,当latch锁个数为0的时分开释悉数等候线程。
*/
publi变量值c void countDown() {
sync.releaseShared(1);变量泵
}
pub变量lic long getCount() {线程池
return sync.getCount(源码编辑器编程猫);
}
public String toString() {
ret线程撕裂者urn super.toString() + "[Count = " + sync.getCount() + "]";
}
}

首要从结构办法来看,CountDownLatch 供给了有参结构函数:

public CountDownLatch(int cou线程池创立的四种nt) {
if (count < 0) throw new IllegalArgumentException("co线程池面试题unt &l变量的指针其意义是指该变量的t; 0");
this.sync线程的几种状况 = new Sync(count);
}

这儿线程池Syn源码编辑器手机版下载c 类是 CountDownLatch 内部线程池的七个参数集成 AQS 结束的一个内部类。

Sync(int count) {
setState(count);
}

Sync 的结构线程撕裂者函数中,调用的是 AQSsetSt线程和进程的差异是什么ate 办法修正 state 值,将 state 值修正为 count 值。

经过上面的介绍,关于 CountDownLatch 类来说,运用最多的便线程池面试题countDownawait 办法。

3.1 countDown() 办法

public void countDown() {
sync.releaseShared(1);
}
/**AQS类中界说的该办法*/
public final boolean rel源码编辑器手机版下载ease源码本钱Shared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return tru源码e;
}
return fals变量类型有哪些e;
}

count源码本钱Down 办法内部是调用 SyncreleaseShared线程是什么意思法,测验开释公共锁状况。

protected boolean tryReleaseShared(int releases) {
// Decremen源码t count; signal when transition to zero
for (;;) {
int c = getState();
if变量英文 (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}

采用自旋的办法,获取当时 state 值,假定 state 值为 0 就回来 false,即开释失利。反之则 state-1,经过 CAS 操作成功,回来 nextc == 0;当终究经过咨询的办法回来 true 的时分(state == 0),则实施 r源码交易网站源码eleaseShared 办法中的变量的界说 doReleaseShared() 办法变量名的命名规矩,在 doReleaseShared() 办法内部经过 unparkSuccessor() 办法唤醒堵塞的线程开端实施。

3.2 await() 办法

public void await() th线程池原理rows InterruptedException {
sync.acquireShar变量名edInterruptibly(1);
}
/***AQS中的办法*/
public final void acquireSharedInterruptibly(int arg)
throws Int变量类型有哪些errupted线程是什么意思Exception {
if (Thread.变量名的命名规矩interrupted())
throw new InterruptedExce线程安全ption();
if (tryAcquireSha源码之家r线程池创立的四种ed(arg) < 0)
do变量的界说AcquireSharedInter线程的几种状况ruptibly(arg);
}
protected int tryAcq变量是什么意思uireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}

这儿调用 acquireSharedInterruptibly() 办法恳求锁,假定锁被占有 state!=0,则经过doAcquireSharedI源码年代nterruptibly变量英文() 进行锁恳求。

4. 总结

CountDownLatch 通常可用于以下场景:

  • 确保某个核算在其需求的悉数资源都被初始化之后才继续实施。
  • 确保线程池某个服务在其依托的悉数其他服务都已建议后才建议。
  • 等候知道某个操作的悉数源码本钱者都安排妥当在继源码年代续实施。