java并发包-CountDownLatch CyclicBarrier Semaphore 案例

1.CountDownLatch案例

        --调用.await()阻塞等待

        --调用countDown()方法每次递减1,直到为0,启动所有等待的线程

package com.roger.juc;

import java.util.concurrent.CountDownLatch;

/**
 * java并发包-CountDownLatch计数器
 * <p>
 * 一个裁判
 * 五个运动员
 * 裁判需要等到所有的运动员都就位了,才能下达起跑的指令
 * 等所有的运动员全都完成所跑赛程,才能下达结束指令
 */
public class CountDownLatchMain {

    public static void main(String[] args) throws Exception{
        int num = 5;
        CountDownLatch sportLatch = new CountDownLatch(1);
        CountDownLatch judgeLatch = new CountDownLatch(num);
        for (int i = 1; i <= num; i++) {
            new Thread(new Sporter(sportLatch,judgeLatch,String.valueOf(i))).start();
        }
        Thread.sleep(100);
        System.out.println("所有的运动员已就绪");
        System.out.println("裁判下达起跑指令");
        sportLatch.countDown();
        System.out.println("裁判下达起跑指令后,等待所有运动员跑完全程");
        judgeLatch.await();
        System.out.println("所有运动员跑完全程.");
        System.out.println("比赛结束,裁判统计运动员的成绩.");
    }

    static class Sporter implements Runnable {

        private CountDownLatch sportLatch;
        private CountDownLatch judgeLatch;
        private String name;

        public Sporter(CountDownLatch sportLatch, CountDownLatch judgeLatch, String name) {
            this.sportLatch = sportLatch;
            this.judgeLatch = judgeLatch;
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println("运动员" + name + "已就绪...");
            try {
                sportLatch.await();
                Thread.sleep((long) (Math.random()*10000));
            }catch (InterruptedException e){

            }finally {
                System.out.println("运动员" + name + "已到达目的地...");
                judgeLatch.countDown();
                System.out.println("裁判记录运动员" + name + "的成绩");
            }
        }
    }
}

某一次运行结果:

运动员1已就绪...
运动员3已就绪...
运动员5已就绪...
运动员2已就绪...
运动员4已就绪...
所有的运动员已就绪
裁判下达起跑指令
裁判下达起跑指令后,等待所有运动员跑完全程
运动员3已到达目的地...
裁判记录运动员3的成绩
运动员4已到达目的地...
裁判记录运动员4的成绩
运动员5已到达目的地...
裁判记录运动员5的成绩
运动员1已到达目的地...
裁判记录运动员1的成绩
运动员2已到达目的地...
裁判记录运动员2的成绩
所有运动员跑完全程.
比赛结束,裁判统计运动员的成绩.

2.CyclicBarrier案例

    --调用await()方法每次递增1,直到达到某个临界值,才能执行下一个任务

    --调用reset()方法重置,从临界值回到起点,循环使用

package com.roger.juc;

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

/**
 * 5个生死兄弟,相约去喝酒,并约定只有等到所有的兄弟都到齐,
 * 才可以开喝,不然要一直等待
 */
public class CyclicBarrierMain {

    public static void main(String[] args) {
        int num = 5;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(num, new Runnable() {
            @Override
            public void run() {
                System.out.println("所有兄弟已到达");
                System.out.println("开喝....");
            }
        });

        for (int i = 1; i <= num; i++) {
            new Thread(new Brother(cyclicBarrier, String.valueOf(i))).start();
        }

    }

    static class Brother implements Runnable {

        private CyclicBarrier cyclicBarrier;
        private String name;

        public Brother(CyclicBarrier cyclicBarrier, String name) {
            this.cyclicBarrier = cyclicBarrier;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                Thread.sleep((long) (Math.random() * 10000));
                System.out.println("兄弟" + name + "到达...");
                cyclicBarrier.await();
            } catch (InterruptedException e) {

            } catch (BrokenBarrierException e) {

            }
        }
    }
}

 某次的允许结果:

兄弟3到达...
兄弟2到达...
兄弟5到达...
兄弟1到达...
兄弟4到达...
所有兄弟已到达
开喝....

3.Semaphore 案例

package com.roger.juc;

import java.util.concurrent.Semaphore;

/**
 * 一个厕所只有3个坑位,但是有10个人来上厕所,那怎么办?
 * 假设10的人的编号分别为1-10,并且1号先到厕所,10号最后到厕所。
 * 那么1-3号来的时候必然有可用坑位,顺利如厕,
 * 4号来的时候需要看看前面3人是否有人出来了,如果有人出来,进去,否则等待。
 * 同样的道理,4-10号也需要等待正在上厕所的人出来后才能进去,
 * 并且谁先进去这得看等待的人是否有素质,是否能遵守先来先上的规则。
 */
public class SemaphoreMain {

    public static void main(String[] args) {
        int pepoleNum = 10;
        //测试只有3个坑位
        Semaphore toiletCount = new Semaphore(3);
        for (int i = 1; i <= pepoleNum; i++) {
            new Thread(new Toilet(String.valueOf(i),toiletCount)).start();
        }
    }

    static class Toilet implements Runnable {

        private String name;
        private Semaphore toiletCount;

        public Toilet(String name, Semaphore semaphore) {
            this.name = name;
            this.toiletCount = semaphore;
        }

        @Override
        public void run() {
            int availablePermits = toiletCount.availablePermits();
            if (availablePermits > 0) {
                System.out.println("厕所有坑位");
            }else{
                System.out.println(name + "等待...");
            }

            try {
                //申请资源
                toiletCount.acquire();
                System.out.println(name + "上厕所....");
                Thread.sleep((long) (Math.random() * 10000));

            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println(name + "上完厕所....");
                //释放资源
                toiletCount.release();
            }
        }
    }
}

某一次的允许结果

厕所有坑位
1上厕所....
厕所有坑位
2上厕所....
厕所有坑位
5上厕所....
4等待...
8等待...
10等待...
3等待...
9等待...
6等待...
7等待...
1上完厕所....
4上厕所....
5上完厕所....
8上厕所....
2上完厕所....
10上厕所....
4上完厕所....
3上厕所....
8上完厕所....
9上厕所....
3上完厕所....
6上厕所....
9上完厕所....
7上厕所....
10上完厕所....
7上完厕所....
6上完厕所....

猜你喜欢

转载自blog.csdn.net/lihongtai/article/details/84300718