使用CountDownLatch进行并发测试

package com.example;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class CountDownLatchDemo {

    public static void main(String[] args) throws InterruptedException {
        final MyNumber myNumber = new MyNumber();
        AtomicInteger integer = new AtomicInteger(0);

        int threadCount = Runtime.getRuntime().availableProcessors();
        ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
        final CountDownLatch concurrentLatch = new CountDownLatch(threadCount);
        final CountDownLatch concurrentLatchV2 = new CountDownLatch(threadCount);
        final CountDownLatch completedLatch = new CountDownLatch(threadCount);
        System.out.println("threadCount: " + threadCount);

        for (int i = 0; i < threadCount; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 保证同时并发
                        concurrentLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    for (int i = 0; i < 10000; i++) {
                        myNumber.increase();
                    }

                    try {
                        concurrentLatchV2.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    for (int i = 0; i < 10000; i++) {
                        integer.incrementAndGet();
                    }

                    completedLatch.countDown();
                }
            });

            concurrentLatch.countDown();
            concurrentLatchV2.countDown();
        }


        completedLatch.await();

        System.out.println("result: " + myNumber.value());
        System.out.println("resultV2: " + integer.get());

        // shutdown
        // 启动有序关闭,其中执行先前提交的任务,但不会接受新任务。 如果已经关闭,调用没有额外的效果。
        // 此方法不等待先前提交的任务完成执行。 使用awaitTermination来做到这一点。
        executorService.shutdown();
        // maximum wait 1000 ms
        // awaitTermination
        // 阻塞直到所有任务在关闭请求后完成执行,或发生超时,或当前线程被中断,以先发生者为准。
        if (!executorService.awaitTermination(1000, TimeUnit.MILLISECONDS)) {
            // shutdownNow
            // 尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。
            // 此方法不会等待主动执行的任务终止。 使用awaitTermination来做到这一点。
            // 除了尽力尝试停止处理正在执行的任务之外,没有任何保证。 例如,典型的实现将通过Thread.interrupt取消,因此任何未能响应中断的任务可能永远不会终止。
            executorService.shutdownNow();
        }
        if (!executorService.isShutdown()) {
            System.out.println("executorService still not shutdown.");
        }
    }

    private static class MyNumber {
        private int num = 0;

        public void increase() {
            num++;
        }

        public int value() {
            return num;
        }
    }

}
posted @ 2021-10-23 16:13  liqipeng  阅读(197)  评论(0编辑  收藏  举报