美文网首页
CountDownLatch的使用

CountDownLatch的使用

作者: 永远的太阳0123 | 来源:发表于2019-01-12 16:58 被阅读0次

1 CountDownLatch

CountDownLatch.Sync继承了AbstractQueuedSynchronizer,重写了tryAcquireShared方法和tryReleaseShared方法。

public class CountDownLatch {

    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;
        }

        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;
            }
        }
    }

    private final Sync sync;

    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }

    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() + "]";
    }
}

2 CountDownLatch图解

state大于0时,所有调用了await方法的线程都会被阻塞;state等于0时,所有被阻塞的线程一起通过栅栏。


3 CountDownLatch使用案例1

3.1 Driver

public class Driver1 {

    public static void main(String[] args) {

        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(10);

        for (int i = 0; i < 10; i++)
            new Thread(new Worker1(startSignal, doneSignal)).start();

        sleep(1);
        System.out.println("开始执行任务");
        startSignal.countDown();
        try {
            doneSignal.await();
            System.out.println("已完成所有任务");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void sleep(int second) {
        try {
            TimeUnit.SECONDS.sleep(second);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

3.2 Worker

public class Worker1 implements Runnable {

    private final CountDownLatch startSignal;
    private final CountDownLatch doneSignal;

    public Worker1(CountDownLatch startSignal, CountDownLatch doneSignal) {
        super();
        this.startSignal = startSignal;
        this.doneSignal = doneSignal;
    }

    @Override
    public void run() {
        try {
            startSignal.await();
            doWork();
            doneSignal.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    void doWork() {
        try {
            TimeUnit.SECONDS.sleep(1);
            System.out.println(Thread.currentThread().getName() + ": 已完成任务");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

4 CountDownLatch使用案例2

4.1 Driver

public class Driver2 {

    public static void main(String[] args) {
        CountDownLatch doneSignal = new CountDownLatch(10);
        Executor e = Executors.newFixedThreadPool(5);

        for (int i = 1; i <= 10; i++)
            e.execute(new Worker2(doneSignal, i));

        try {
            doneSignal.await();
            System.out.println("已完成所有任务");
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }

}

4.2 Worker

public class Worker2 implements Runnable {

    private final CountDownLatch doneSignal;
    private final int i;

    Worker2(CountDownLatch doneSignal, int i) {
        this.doneSignal = doneSignal;
        this.i = i;
    }

    @Override
    public void run() {
        doWork(i);
        doneSignal.countDown();
    }

    void doWork(int i) {
        try {
            TimeUnit.SECONDS.sleep(1);
            System.out.println(Thread.currentThread().getName() + ": 已完成第" + i + "项任务");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

相关文章

  • countdown设计模式

    使用JDK自带的countdownLatch

  • 8. Java中的并发工具类

    CountDownLatch 作用:等待一个或多个线程执行完成; 使用: CountDownLatch cdl =...

  • JUC并发编程-6.CountDownLatch源码解析

    1.CountDownLatch相关API使用 运行结果 2.CountDownLatch相关API解读 new ...

  • CountDownLatch的使用

    一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 Co...

  • CountDownLatch的使用

    1 CountDownLatch CountDownLatch.Sync继承了AbstractQueuedSync...

  • CountDownLatch的使用

    CountDownLatch是java中一个协调多线程的工具类,假如多线程在执行后,需要等待所有都执行完再执行下一...

  • CountDownLatch 使用

    java.util.concurrent.CountDownLatch是一个并发结构,它允许一个或多个线程等待一组...

  • CountDownLatch使用

    该类是一个同步功能的辅助类,使用效果是给定一个技术,当使用这个类的线程判断计数不为0时,则成wait状态,如果为0...

  • CountDownLatch使用

    CountDownLatch使用 CountDownLatch是java中的一个同步工具类.用于对线程的阻塞和唤醒...

  • CountDownLatch使用

    CountDownLatch是JAVA提供在java.util.concurrent包下的一个辅助类。 内部有一个...

网友评论

      本文标题:CountDownLatch的使用

      本文链接:https://www.haomeiwen.com/subject/mvecdqtx.html