Java等待异步线程池跑完再执行指定方法的三种方式(condition、CountDownLatch、CyclicBarrier)

Java等待异步线程池跑完再执行指定方法的三种方式(condition、CountDownLatch、CyclicBarrier)

以下指定的方法即打印villageList2的长度

1、juc中condition接口提供的await、signal、signalAll方法,需配合lock

List<Integer> villageList = new ArrayList<>();
    List<Integer> villageList2 = new ArrayList<>();
    villageList.add(1);
    villageList.add(2);
    villageList.add(3);
    ExecutorService threadPool = Executors.newFixedThreadPool(2);

    Lock lock = new ReentrantLock();
    Condition cond = lock.newCondition();
    for(int flag = 0;flag<villageList.size();flag++){
        Integer i = villageList.get(flag);
        threadPool.execute(() -> {
            try {
                villageList2.add(i);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(villageList2.size() == villageList.size()){
                lock.lock();
                cond.signal();
                lock.unlock();
            }
        });
    }
    lock.lock();
    try {
        cond.await(5, TimeUnit.SECONDS);
        lock.unlock();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(villageList2.size());
    threadPool.shutdown();
}

2、CountDownLatch

List<Integer> villageList = new ArrayList<>();
List<Integer> villageList2 = new ArrayList<>();
villageList.add(1);
villageList.add(2);
villageList.add(3);
final CountDownLatch count = new CountDownLatch(villageList.size());
ExecutorService threadPool = Executors.newFixedThreadPool(2);

for(Integer i:villageList){
    threadPool.execute(() -> {
        try {
            villageList2.add(i);
            count.countDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    });}
try {
    count.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println(villageList2.size());
threadPool.shutdown();

3、CyclicBarrier

List<Integer> villageList = new ArrayList<>();
        List<Integer> villageList2 = new ArrayList<>();
        villageList.add(1);
        villageList.add(2);
        villageList.add(3);
        ExecutorService threadPool = Executors.newFixedThreadPool(villageList.size());
        CyclicBarrier barry = new CyclicBarrier(villageList.size(), new Runnable() {
            @Override
            public void run() {
                System.out.println(villageList2.size());
            }
        });

        for(Integer i:villageList){
            threadPool.execute(() -> {
                try {
                    villageList2.add(i);
                    System.out.println(System.currentTimeMillis());
                    barry.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        threadPool.shutdown();
        }

CountDownLatch和CyclicBarrier的比较
1.CountDownLatch是减计数方式,countDown()方法只参与计数不会阻塞线程,而CyclicBarrier是加计数方式,await()方法参与计数,会阻塞线程。
2.CountDownLatch计数为0无法重置,而CyclicBarrier计数达到初始值,则可以重置,因此CyclicBarrier可以复用。

附:CountDownLatch有发令枪的效果,可以用来并发测试
Java等待异步线程池跑完再执行指定方法的三种方式(condition、CountDownLatch、CyclicBarrier)_第1张图片

你可能感兴趣的:(多线程)