线程池+countDownLatch的使用案例

发布时间 2023-06-30 15:37:40作者: 牛奶配苦瓜

1.线程池+countDownLatch+时间的测试

1.1 使用目的说明

下面代码的目的是当SimpleDateFormat 多线程调用的情况下,被用作为全局变量的时候会出现线程不安全的情况
解决的方法是:可以通过使用局部变量或者利用java中自带的线程安全时间工具类LocalDateTime


    /**
     * 定义一个全局的时间变量simpleDateFormat
     */
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 使用ThreadFactoryBuilder定义一个线程池
     */
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();

    private static ExecutorService pool = new ThreadPoolExecutor(5,200,0L,
            TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(1024),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());

    /**
     * 定义一个CountDownLatch,保证所有子线程执行完之后主线程在执行
     */
    private static CountDownLatch  countDownLatch = new CountDownLatch(100);

    public static void main(String[] args) throws Exception {
        Set<Object> dates = Collections.synchronizedSet(new HashSet<>());
        for (int i = 0; i < 100; i++) {
            //获取当前时间
            Calendar calendar = Calendar.getInstance();
            int finalI = i;
            pool.execute(()->{
                calendar.add(Calendar.DATE,finalI);
                //线程不安全,dates 永远会小于100 ---- 解决方案:1.使用局部变量 2.加锁 3.静态ThreadLocal返回值 4.使用DateTimeFormatter
                String format = simpleDateFormat.format(calendar.getTime());
                dates.add(format);
                countDownLatch.countDown();
            });
        }

        countDownLatch.await();
        System.out.println("dates.size() = " + dates.size());
    }