并发控制工具类CountDownLatch、CyclicBarrier、Semaphore

并发控制工具类CountDownLatch、CyclicBarrier、Semaphore

1.CountDownLatch

可以使一个或多个线程等待其他线程各自执行完毕后再执行。 CountDownLatch 是多线程控制的一种工具,它被称为 门阀、 计数器或者闭锁。这个工具经常用来用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。
让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒,CountDownLatch主要有2个方法,当一个或多个线程调用await方法时,调用线程会被阻塞,其他线程调用countDown方法时计数器减一(调用countDown方法不会阻塞线程),当计数器的值变为0时,此时调用方法被阻塞的线程会被唤醒,继续执行
countDown 方法时计数器减一
await 尝试唤醒,当计数器的值变为0时,才会被唤醒

实例:学生上自习,当学生走完后才能锁门

public class CountDownLatchDemo {
    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(Thread.currentThread().getName()+"\t &&&&&&&&&&班长锁门");
    }
}

输出
0 上完自习离开
4 上完自习离开
3 上完自习离开
2 上完自习离开
1 上完自习离开 main
&&&&&&&&&&班长锁门

2.CyclicBarrier

N个线程相互等待,任何一个线程没有到达或完成时,所有的线程都必须互相等待。与CountDownLatch相反。必须要达到某个值才会被唤醒。
await():线程调用 await 方法通知 CyclicBarrier 本线程已经到达屏障
并发控制工具类CountDownLatch、CyclicBarrier、Semaphore_第1张图片
实例:集齐7颗龙珠召唤神龙

 public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
            System.out.println("……召唤神龙……");
        });

        for (int i = 1; i <= 7; i++) {
            int finalI = i;
            new Thread(()->{

                System.out.println(Thread.currentThread().getName()+"\t 收集到:"+finalI+"颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

我理解就是 cyclicBarrier.await();要被调够 创建CyclicBarrier 时设置的次数,才会真的触发 创建CyclicBarrier的内容

输出

1 收集到:1颗龙珠
5 收集到:5颗龙珠
3 收集到:3颗龙珠
7 收集到:7颗龙珠
2 收集到:2颗龙珠
6 收集到:6颗龙珠
4 收集到:4颗龙珠
……召唤神龙……

3.Semaphore

Semaphore
①多个共享资源的互斥使用
②并发线程数控制
(信号量)可以用来限制能同时访问共享资源的线程上限,它内部维护了一个许可的变量,也就是线程许可的数量


acquire() 表示阻塞并获取许可 (没获取到信号的线程阻塞等待)
tryAcquire() 方法在没有许可的情况下会立即返回 false,要获取许可的线程不会阻塞(没获取到线程的拿着返回值false直接往下继续)
release() 表示释放许可 int availablePermits():返回此信号量中当前可用的许可证数。
getQueueLength():返回正在等待获取许可证的线程数。
hasQueuedThreads():是否有线程正在等待获取许可证。
reduction个许可证 Collection getQueuedThreads():返回所有等待获取许可证的线程集合

并发控制工具类CountDownLatch、CyclicBarrier、Semaphore_第2张图片

实例:停车场抢车位

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <=6 ; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"\t 抢到车位");

                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+"\t 停车3秒后离开");
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

输出
1 抢到车位
3 抢到车位
2 抢到车位
1 停车3秒后离开
3 停车3秒后离开
4 抢到车位
2 停车3秒后离开
5 抢到车位
6 抢到车位
4 停车3秒后离开
6 停车3秒后离开
5 停车3秒后离开

你可能感兴趣的:(java,java,开发语言)