编程语言
首页 > 编程语言> > java线程计数器

java线程计数器

作者:互联网

一、前言

主要记录下CountDownLatch、CyclicBarrer、Semaphore 用法

二、CountDownLatch

经常遇到一种场景,线程还未执行完毕,主函数执行完了,为了避免这种情况发生可以使用countDownLatch 计数器,会阻塞主函数,等待线程执行完毕后,才放行

public static void main(String[] args) throws InterruptedException {

    CountDownLatch downLatch = new CountDownLatch(5);

    for (int i = 0; i < 5; i++) {
        final int num = i;
        new Thread(()->{
            System.out.println("线程"+Thread.currentThread().getName()+" "+(num+1));
            downLatch.countDown();
        },String.valueOf(num+1)).start();
    }
    downLatch.await();

    System.out.println("线程"+Thread.currentThread().getName()+" 执行完毕。。。");
}

 

countDownLatch 会阻塞线程,计数器依次递减,减到0时,放行,执行后续代码

三、CyclicBarrer

加方计数器,与CountDownLatch 想反,当满足某种条件时才执行后续步骤

public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
        System.out.println("放行 cyclicBarrier...");
    });

    for (int i = 0; i < 5; i++) {
        final int num = i;
        new Thread(() -> {
            System.out.println("线程" + Thread.currentThread().getName());
            try {
                cyclicBarrier.await(); //执行一次,+1,阻塞等待,达到计数器后,解除阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        },String.valueOf(num + 1)).start();

        System.out.println("等待执行:"+cyclicBarrier.getNumberWaiting());
    }
}

 

CyclicBarrer未达到设置的数量时,cyclicBarrier.await() 一直会阻塞,达到后放行,

四、Semaphore

信号量计数器,一次只能是指定个数线程,其他线程等待,线程释放后,其他线程才可进入,常用场景限流

public static void main(String[] args) {
   Semaphore semaphore = new Semaphore(2);  //通行信号量 

    for (int i = 0; i < 6; i++) {
        final int num = i;
        new Thread(() -> {
            try {
                semaphore.acquire(); //获取控制权信号量-1
                System.out.println("线程" + Thread.currentThread().getName() + "获得控制权");
               System.err.println("线程" + Thread.currentThread().getName() + "释放控制权");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release(); //释放控制权,信号量 +1
            }
        },String.valueOf(num+1)).start();
    }
}

 

设置一次通行2个线程,6个线程,只有其他线程放弃控制权,后续线程才可获得

五、总结

CountDownLatch:减法计数器,归零后解除阻塞

CyclicBarrer: 加法计数器,达到设定值,解除阻塞,放行

Seamphore: 信号量计数器,一次执行通过指定线程,线程获取信后,信号量-1,归零时阻塞,释放后,信号量后+1,信号量>0时不阻塞。

标签:java,Thread,System,信号量,计数器,线程,println
来源: https://www.cnblogs.com/yifanSJ/p/16317159.html