CountDownLatch/CyclicBarrier/Semaphore

90 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

1.CountDownLatch

用法:通过计数器 来限制某一线程在其他线程之后在执行,示例代码如下

public static void main(String[] args) throws InterruptedException {
    CountDownLatch countDownLatch = new CountDownLatch(10);
    for (int i = 0; i <10 ; i++) {
        new Thread(()->{
         System.out.println(Thread.currentThread().getName()+" \t"+"进来了");
         countDownLatch.countDown();
        },String.valueOf(i)).start();
    }
    countDownLatch.await();
    System.out.println("主线程开始了");
}

运行结果:

0 	进来了
1 	进来了
2 	进来了
3 	进来了
7 	进来了
4 	进来了
5 	进来了
6 	进来了
8 	进来了
9 	进来了
主线程开始了

2.CyclicBarrier

解释:有多少个线程调用它的await方法后,再调用构造器里的线程 示例:

public static void main(String[] args) throws InterruptedException {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new Runnable() {
        @Override
        public void run() {
            System.out.println("当前线程"+Thread.currentThread().getName());
        }
    });
    for (int i = 0; i <10 ; i++) {
        new Thread(()->{
         System.out.println(Thread.currentThread().getName()+" \t"+"进来了");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        },String.valueOf(i)).start();
    }
}

以上代码就是说当有十个线程在await之后 ,执行runnable里面的方法,结果如下

1 	进来了
5 	进来了
4 	进来了
3 	进来了
2 	进来了
0 	进来了
6 	进来了
7 	进来了
9 	进来了
8 	进来了
当前线程8

3.Semaphore

可用来控制资源权限,例如只有三个停车位 有六辆车要停,这个时候只能有三个先停,其他三个进入等待状态,前三个完成走之后 把位置让出来,后面才能进 示例如下

public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(3);
    for (int i = 0; i <6 ; i++) {
        new Thread(()->{
            try {
                semaphore.acquire();
                System.out.println(Thread.currentThread().getName()+" \t"+"进来了");
                Thread.sleep(2000);
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },String.valueOf(i)).start();
    }
}

运行以上代码 会发现先进来三个 过了两秒后面三个才会进来

0 	进来了
1 	进来了
2 	进来了
3 	进来了
5 	进来了
4 	进来了

总结

CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

  CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

  而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

  另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限