CountDownLatch
前言
今天博主将为大家分享一下使用Java 多线程条件通行工具——CountDownLatch,不喜勿喷,如有异议欢迎讨论!
-
CountDownLatch和CyclicBarrier的区别,其实比较简单,CountDownLatch对执行任务的线程。比如有A,B,C三个线程,那么如果A是设置了countDown.await()这个方法,那么B和C就只能等到A了,什么时候A准备好了,那么B和C才可以执行.
-
典型的场景就是,比如A需要从远程服务器拿到某个资源,然后B和C的执行,需要依赖A这个资源,但是又可能,A执行的时候,拿到的资源还是空的或者没有就绪,那么只有通过在主线程里,另外起一个线程,比如叫D吧,他循环判断A请求的资源是否就绪,而在主线程里在B和C执行以前,统一设置一个 countDown.await()方法。只有当D确认资源状态以后,并且调用了 countDown.countDown(2) 这里是2是假设的,到0,就表示OK了,那么被等待的方法才能继续执行下去
-
而 CyclicBarrier呢,A B C三个都要准备好了,不然没有办法继续下去.
以下所写内容均与以前的文章有联系可以前往博文查看,陈永佳的博客
CountDownLatch的作用
线程进入等待后,需要计数器达到0才能通行。
- CountDownLatch(int)
构造方法,指定初始计数。 - await()
等待计数减至0。 - await(long, TimeUnit)
在指定时间内,等待计数减至0。 - countDown()
计数减1。 - getCount()
获取剩余计数。
例子1:主线程创建了若干子线程,主线程需要等待这若干子线程结束后才结束。
例子2:线程有若干任务,分多个线程来完成,需要等待这若干任务被完成后,才继续运行处理。
源码如下:
/**
* @since 1.5
* @author Doug Lea
*/
public class CountDownLatch {
private final Sync sync;
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
// 当数量达到0时,才能通行,否则阻塞
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
// 如果数量达到0,则释放失败
if (c == 0)
return false;
int nextc = c-1;
// 尝试把数量递减
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
public void await() throws InterruptedException {
// 获取共享锁
sync.acquireSharedInterruptibly(1);
}
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
// 尝试获取共享锁
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
public void countDown() {
// 释放共享锁
sync.releaseShared(1);
}
public long getCount() {
return sync.getCount();
}
public String toString() {
return super.toString() + "[Count = " + sync.getCount() + "]";
}
}
给个栗子,代码如下:
package com.test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
/**
*
* @Description: Java 多线程条件通行工具——CountDownLatch
* @ClassName: CountDownLatch.java
* @author ChenYongJia
* @Date 2019年4月17日 晚上22:54
* @Email chen87647213@163.com
*/
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
CountDownLatchTest test = new CountDownLatchTest();
CountDownLatch latch = new CountDownLatch(1);
Thread t1 = new Thread(test.new MapOper(latch));
Thread t2 = new Thread(test.new MapOper(latch));
Thread t3 = new Thread(test.new MapOper(latch));
Thread t4 = new Thread(test.new MapOper(latch));
t1.setName("Thread1");
t2.setName("Thread2");
t3.setName("Thread3");
t4.setName("Thread4");
t1.start();
t2.start();
t3.start();
t4.start();
System.out.println("线程已经启动,休眠一会儿...");
Thread.sleep(1000);
latch.countDown();
}
public class MapOper implements Runnable {
CountDownLatch latch;
public MapOper(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 同步开始!");
}
}
}
控制台输出:
线程已经启动,休眠一会儿...
Thread2 同步开始!
Thread3 同步开始!
Thread1 同步开始!
Thread4 同步开始!
到这里使用Java 多线程条件通行工具——CountDownLatch讲解完毕了,下一篇将为大家讲解Java 多线程条件通行工具——CyclicBarrier!
最后
-
更多参考精彩博文请看这里:《陈永佳的博客》
-
喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/97886.html