Java多线程与并发_同步工具类CountDownLatch,CyclicBarrier和Semaphore

Java多线程与并发_同步工具类CountDownLatch,CyclicBarrier和Semaphore

人处在一种默默奋斗的状态,精神就会从琐碎生活中得到升华

一、CountDownLatch

构造器

  • CountDownLatch(int count) //参数count为计数值

主要方法:

  • await():调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
  • await(long timeout,TimeUnit unit):和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
  • countDown():将count值减1

例子说明:秦灭6国,一统华夏

  • 解释:6个国家陆续被灭后,秦国最后才一统华夏
  • main主线程必须要等前面6个线程完成全部工作后,自己才能开干
public class CountDownLatchDemo {

    public static void main(String[] args) throws InterruptedException {
        //秦灭6国,一统华夏
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 国被灭");
                countDownLatch.countDown();
            },CountryEnums.forEachCountryEnums(i).getRetMsg()).start();
        }
        countDownLatch.await();

        System.out.println("-------main 秦灭6国,一统华夏");
    }
}

国家的枚举类

public enum CountryEnums {
    ONE(0,"韩"),
    TWO(1,"魏"),
    THREE(2,"赵"),
    FOUR(3,"齐"),
    FIVE(4,"楚"),
    SIX(5,"燕")
    ;

    private Integer retCode;
    private String retMsg;

    CountryEnums(Integer retCode, String retMsg) {
        this.retCode = retCode;
        this.retMsg = retMsg;
    }

    public Integer getRetCode() {
        return retCode;
    }

    public void setRetCode(Integer retCode) {
        this.retCode = retCode;
    }

    public String getRetMsg() {
        return retMsg;
    }

    public void setRetMsg(String retMsg) {
        this.retMsg = retMsg;
    }

    public static CountryEnums forEachCountryEnums(Integer index) {
        for (CountryEnums element : values()) {
            if (element.getRetCode() == index) {
                return element;
            }
        }
        return null;
    }
}

结果

韩	 国被灭
齐	 国被灭
赵	 国被灭
魏	 国被灭
楚	 国被灭
燕	 国被灭
-------main 秦灭6国,一统华夏

Process finished with exit code 0

二、CyclicBarrier

字面意思是可循环(Cyclic)使用的屏障(Barrier),他要做的事情是,
让一组线程到达一个屏障(也可以叫同步点)时被阻塞,
直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
线程进入屏障通过CyclicBarrier的await()方法

构造器

  • CyclicBarrier(int parties, Runnable barrierAction)
  • CyclicBarrier(int parties)

参数parties指让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。

主要方法

  • int await()
  • int await(long timeout, TimeUnit unit)

第一个版本比较常用,用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;

第二个版本是让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。

例子说明:集齐7颗龙珠召唤神龙

public class CyclicBarrierDemo {

    private static final int NUMBER = 7;

    public static void main(String[] args) {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER,() -> {
            System.out.println("*****召唤神龙*****");
        });

        for (int i = 1; i <= NUMBER; i++) {
            int tempInt = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 收集到第" + tempInt + "\t 颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

结果

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

Process finished with exit code 0

三、Semaphore

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。

public class SemaphoreDemo {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);//模拟3个停车位

        for (int i = 1; i <= 6; i++) {//模拟6部汽车
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t 抢占了车位");
                    TimeUnit.SECONDS.sleep(new Random().nextInt(8));
                    System.out.println(Thread.currentThread().getName() + "\t 离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

结果:

1	 抢占了车位
3	 抢占了车位
2	 抢占了车位
2	 离开了车位
3	 离开了车位
4	 抢占了车位
5	 抢占了车位
1	 离开了车位
6	 抢占了车位
4	 离开了车位
5	 离开了车位
6	 离开了车位

Process finished with exit code 0

你可能感兴趣的:(Java多线程与并发)