java并发编程中必须学会的三个常用的辅助类(CountDownLatch,CyclicBarrier,Semaphore)

1. CountDownLatch
在这里插入图片描述
CountDownLatch用给定的计数初始化。 [await]方法阻塞,直到由于countDown()方法的[调用]而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await [调用立即]返回。 这是一个一次性的现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用[CyclicBarrier] 。

package com.add;

import java.util.concurrent.CountDownLatch;

//计数器
public class CountDownLatchDemo01 {
    public static void main(String[] args) throws InterruptedException {
        //总数是6,类似于倒计时.参数设置为6,即等待6个线程执行完毕
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"GO OUT");
                countDownLatch.countDown();//-1
            },String.valueOf(i)).start();
        }
        countDownLatch.await();//等待计数器归零,然后在向下执行

​        System.out.println("close door");}
}

原理:

//总数是6,类似于倒计时.参数设置为6,即等待6个线程执行完毕
CountDownLatch countDownLatch = new CountDownLatch(6);
countDownLatch.countDown();//-1

countDownLatch.await();//等待计数器归零,然后在向下执行

每次有线程调用countDown()数量减一假如计数器变为0,countDownLatch.await()就会被唤醒,继续执行!
2.CyclicBarrier
在这里插入图片描述

package com.add;

import com.sun.org.apache.xerces.internal.xs.ItemPSVI;

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

/**

 * 集齐七龙珠召唤神龙

 * 召唤控住的线程
   */
   public class CyclicBarrierDemo02 {
   public static void main(String[] args) {
       CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
           System.out.println("召唤神龙成功!"); });
       for (int i = 0; i < 7; i++) {
           final int temp = i;
           new  Thread(()->{
              // cyclicBarrier.getParties(); 由于数组自动递增,这里可以不设置
               System.out.println(Thread.currentThread().getName()+"收集了第"+temp+"颗龙珠");try {
   ​                cyclicBarrier.await();} catch (InterruptedException e) {
   ​                e.printStackTrace();} catch (BrokenBarrierException e) {
   ​                e.printStackTrace();}}).start();}
   }
   }

3. Semaphore
semaphore:信号量
在这里插入图片描述
代码:

package com.add;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo03 {
    public static void main(String[] args) {
        //限流的时候,会用到
        Semaphore semaphore = new Semaphore(5, true);
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                //acquire()都会阻塞(得到许可证),release()添加许可证,潜在地释放阻塞获取方(释放)
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"抢到车位");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+"离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

原理: acquire()获得,假设如果已经满了,等待被释放为止
release()释放,会将当前的信号量释放+1,然后唤醒等待的线程!
作用:多个共享资源互斥的使用!并发限流,控制最大的限流数.

原创文章 32 获赞 52 访问量 641

猜你喜欢

转载自blog.csdn.net/qq_42400763/article/details/105820891