4、CountDownLatch、CyclicBarrier 和Semaphore 使用过吗?

1、CountDownLatch (关灯走人)

让一些线程堵塞直到另一个线程完成一系列操作后才被唤醒。CountDownLatch 主要有两个方法,当一个或多个线程调用 await 方法时,调用线程会被堵塞,其他线程调用 countDown 方法会将计数减一(调用 countDown 方法的线程不会堵塞),当计数其值变为零时,因调用 await 方法被堵塞的线程会被唤醒,继续执行。

假设我们有这么一个场景,教室里有班长和其他6个人在教室上自习,怎么保证班长等其他6个人都走出教室在把教室门给关掉。

public class CountDownLanchDemo {
    
    
    public static void main(String[] args) {
    
    
        for (int i = 0; i < 6; i++) {
    
    
            new Thread(() -> {
    
    
                System.out.println(Thread.currentThread().getName() + " 离开了教室...");
            }, String.valueOf(i)).start();
        }
        System.out.println("班长把门给关了,离开了教室...");
    }
}

此时输出:

0 离开了教室...
1 离开了教室...
2 离开了教室...
3 离开了教室...
班长把门给关了,离开了教室...
5 离开了教室...
4 离开了教室...

发现班长都没有等其他人理他教室就把门给关了,此时我们就可以使用 CountDownLatch 来控制.

public class CountDownLanchDemo {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
    
    
            new Thread(() -> {
    
    
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName() + " 离开了教室...");
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("班长把门给关了,离开了教室...");
    }
}

此时输出:

0 离开了教室...
1 离开了教室...
2 离开了教室...
3 离开了教室...
4 离开了教室...
5 离开了教室...
班长把门给关了,离开了教室...

2、CyclicBarrier (满车出发)

我们假设有这么一个场景,每辆车只能坐个人,当车满了,就发车。

package com.example.rabbitmq.test.nio;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class cyclicBarrier {
    
    
    public static void main(String[] args) {
    
    
    	//车上共十个座位
        int is=10;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(is,()->{
    
    
            System.out.println("满车出发!!");
        });
        for (int i = 0; i <is ; 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();
        }

    }
}

执行结果:

1	 上车
5	 上车
4	 上车
6	 上车
3	 上车
2	 上车
0	 上车
9	 上车
8	 上车
7	 上车
满车出发!!

3、Semaphore

假设我们有 3 个停车位,6 辆车去抢

package com.example.rabbitmq.test.nio;

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    
    
    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);
                    System.out.println(Thread.currentThread().getName()+"\t "+"出库了...");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }finally {
    
    
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

输出结果:

2	 入库了...
0	 入库了...
2	 出库了...
1	 出库了...
0	 出库了...
3	 入库了...
4	 入库了...
5	 入库了...
3	 出库了...
5	 出库了...
4	 出库了...

猜你喜欢

转载自blog.csdn.net/YL3126/article/details/121805297
今日推荐