java多线程线程池 —— CountDownLatch线程计数器

ThreadPoolExecutor/ExecutorService:线程池,使用线程池可以复用线程,降低频繁创建线程造成的性能消耗,同时对线程的创建、启动、停止、销毁等操作更简便。
CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。
例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
与CountDownLatch的第一次交互是主线程等待其他线程。主线程必须在启动其他线程后立即调用CountDownLatch.await()方法。这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。
其他N 个线程必须引用闭锁对象,因为他们需要通知CountDownLatch对象,他们已经完成了各自的任务。这种通知机制是通过 CountDownLatch.countDown()方法来完成的;每调用一次这个方法,在构造函数中初始化的count值就减1。所以当N个线程都调 用了这个方法,count的值等于0,然后主线程就能通过await()方法,恢复执行自己的任务。
 

import java.util.concurrent.*;

public class CountDownTest {

    public static void main(String[] args) {
        int num = 100;
        //启用线程池(最大不能超过500个)
        ThreadPoolExecutor executor = new ThreadPoolExecutor(50,//核心池大小
                500,//最大池大小
                200,//线程最大空闲时间,超过此空闲时间可以被收回
                TimeUnit.MILLISECONDS, //最大空闲时间的单位
                new ArrayBlockingQueue<Runnable>(10)//用于保存执行任务的队列,可以选择其他不同的队列来做任务管理
        );
        CountDownLatch n = new CountDownLatch(num);

        for (int i = 0; i < num; i++) {
            //启动一个任务
            Task myTask = new Task(i, n);
            executor.execute(myTask);
        }

        System.out.println("全部执行的任务数量:" + executor.getTaskCount());
        System.out.println("已完成的任务数量:" + executor.getCompletedTaskCount());
        System.out.println("线程池中最大线程数量:" + executor.getPoolSize());


        //等待所有线程完毕
        try {
            n.await();
        } catch (InterruptedException e) {
            System.out.println(e);
        }

        //关闭线程池
        executor.shutdown();
    }

}

class Task implements Runnable {

    private int taskNum;
    CountDownLatch n;


    public Task(int num, CountDownLatch n) {
        this.taskNum = num;
        this.n = n;
    }

    public void run() {
        try {

            Thread.sleep(1000);
            System.out.println("擦桌子");

        } catch (Exception e) {
            System.out.println("task " + taskNum + "执行失败");
        }
        //事情干完了
        n.countDown();
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值