码迷,mamicode.com
首页 > 其他好文 > 详细

CountDownLatch

时间:2021-06-22 18:47:48      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:ide   内容   long   row   cep   结果   interrupt   time   for   

在Java中,从JDK1.5后开始引入并发编程序相关的内容,为进一步理解和编写更加高效的应用程序,从java.util.concurrent包下开始了解,对应的并发编程的相关的类。

CountDownLatch类的相关的理解和对应的程序demo编写理解。借助的工具是Idea,首先查看到对应的点就是,并发编程所在的包。

技术图片

 

 

CountDownLatch在java.util.concurrent包下,主要作用是等待线程全部执行完成后,再继续执行下面的操作。使用的业务场景可能是:如在某一线程处理某种业务逻辑前,需要有其他线程的相关数据的先执行初始化,其他线程执行完成后才能执行该线程的处理业务逻辑;保证其在执行业务逻辑时的正确性。可以参考下方的执行图,在执行用户线程A的时候,需要等待A、B、C、D线程执行完对应的业务处理,才能够运行用户线程A。在这种业务场景下可使用CountDownLatch类来完成对应的执行流程。

 技术图片

  对应的使用代码的Demo如下:

public class CountDownLatchTest {
    private static CountDownLatch cdl = new CountDownLatch(4);
    public static void main(String[] args) throws InterruptedException {
        UserRunnable u= new UserRunnable();
        u.setL(2000);
        UserRunnable u1 = new UserRunnable();
        u1.setL(4000);
        UserRunnable u2 = new UserRunnable();
        u2.setL(10000);
        UserRunnable u3 = new UserRunnable();
        u3.setL(15000);

        new Thread(u).start();
        new Thread(u1).start();
        new Thread(u2).start();
        new Thread(u3).start();
     //代表当前的主线程在等待 cdl.await(); System.out.println(
"主线程任务执行结束!"); }   //内部类增加线程运行的细节情况 static class UserRunnable implements Runnable { private long l; public UserRunnable() {} public long getL() { return l; } public void setL(long l) { this.l = l; } public UserRunnable(long l) { this.l = l; } @Override public void run() { try { System.out.println(l+"==============1=============="+System.currentTimeMillis()); Thread.sleep(l); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(l+"==============2=============="+System.currentTimeMillis()); cdl.countDown(); } } }

 

在编写完对应的代码后,运行结果如下:

4000==============1==============1624342340360
10000==============1==============1624342340361
15000==============1==============1624342340362
2000==============1==============1624342340366
2000==============2==============1624342342403
4000==============2==============1624342344364
10000==============2==============1624342350376
15000==============2==============1624342355374
主线程任务执行结束!

在上方运行的结果可以知道,我们等待四个子线程运行完对应的任务后才开始继续运行对应的线程。当我们变更对应的参数时,如new CountDownLatch(1)中的从4变更为1时,表示只要有一个任务执行完成即可继续执行后续的对应的线程工作。

private static CountDownLatch cdl = new CountDownLatch(1);

更改为1后执行的结果如下:

4000==============1==============1624342483910
10000==============1==============1624342483912
15000==============1==============1624342483912
2000==============1==============1624342483913
2000==============2==============1624342485917
主线程任务执行结束!
4000==============2==============1624342487918
10000==============2==============1624342493916
15000==============2==============1624342498916

在学习CountDownLatch时,关注其实现中的主要几个方法,能够更加快速理解其设计的原理以及应用的业务场景

//设置需要等待线程的个数
public CountDownLatch(int count);
//等待其他线程执行完成
public void await();
//等待其他线程完成,超时退出
public boolean await(long timeout, TimeUnit unit);
//某一线程执行完减一操作
public void countDown();

 其中,主要的设计思想方法在其内部类方法Sync上,底层基于AQS机制,保证了在多线程下的相关的操作。

    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) { return (getState() == 0) ? 1 : -1; }      //循环,当对应的数值为0则推出循环 protected boolean tryReleaseShared(int releases) { for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } } }

  

  

CountDownLatch

标签:ide   内容   long   row   cep   结果   interrupt   time   for   

原文地址:https://www.cnblogs.com/jimmy-lc/p/14919475.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!