常用并发工具类的使用

常用并发工具类的使用。

CountDownLatch

CountDownLatch是一个计数器,当计数器的值大于0时,执行等待方法await,阻塞直到计数器的值等于0时,才放行。
Lach有门闩的意思,可以把它理解成一道栅栏,举个生活中的例子,运动员在起跑线上,等待发号员口令,这是运动员调用的是await方法。发号员数"3、2、1“时,调用了三次downCount方法。当值为0时,运动员就开跑。

public class CoundownLatchTest {
    private static final CountDownLatch countDownLatch = new CountDownLatch(5);
    private static List<String> bossList = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        new AssassinateThread("杀手一", "吉诺维斯家族首领").start();
        new AssassinateThread("杀手二", "波纳诺家族首领").start();
        new AssassinateThread("杀手三", "科洛博家族首领").start();
        new AssassinateThread("杀手四", "卢凯塞家族首领").start();
        new AssassinateThread("杀手五", "甘比诺家族首领").start();
        countDownLatch.await();
        // 执行到这里,理论上全部首领刺杀成功
        System.out.println("刺杀成功名单:");
        for (String bossName : bossList) {
            System.out.print(bossName + " ");
        }
    }

    private static class AssassinateThread extends Thread {

        private String bossName;

        public AssassinateThread(String name, String bossName) {
            super(name);
            this.bossName = bossName;
        }

        @Override
        public void run() {
            bossList.add(bossName);
            countDownLatch.countDown(); // 计数器减一
        }
    }
}
CyclicBarrier

Cyclicbarrier叫做循环栅栏,顾名思义,就是可以被循环使用。设立一个屏障,待所有线程到达这个屏障之后,才能执行下一步的代码。注意区别于CountdownLatch的用法,CountdownLatch是一个倒计时器。

public class PlayBasketball {

    // 等待六个人都到的时候,就可以3v3了。
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(6, new Play3v3Thread());

    public static void main(String[] args) {
        System.out.println("永和九年,天朗气清,惠风和畅,与众球星会于天体边之球场,修禊事也。");
        new ReportThread("我").start();
        new ReportThread("迈克尔乔丹").start();
        new ReportThread("科比布莱恩特").start();
        new ReportThread("勒布朗詹姆斯").start();
        new ReportThread("蒂姆邓肯").start();
        new ReportThread("凯文杜兰特").start();
    }

    private static class Play3v3Thread extends Thread {

        @Override
        public void run() {
            System.out.println("所有人到齐,开始3v3");
        }
    }

    private static class ReportThread extends Thread {

        private String name;

        public ReportThread(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name + "到了");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}
Exchanger

用于线程之前交换信息,比如做买卖,有买有卖,有得必有失。

public class ExchangerTest {

    // exchanger可用来线程之前交换信息,比如做买卖,对于卖家,他收了钱。对比买家,他得到货物。
    private static final Exchanger<String> exchanger = new Exchanger<>();

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                String phone = "iphone11";
                try {
                    System.out.println("我是苹果旗舰店,我卖出" + phone + ",挣了" + exchanger.exchange(phone));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                String money = "5999";
                try {
                    System.out.println("我花了"+ money + "买了一部" + exchanger.exchange(money));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
Semaphore

semaphore用来控制一组资源的并发使用,有点类似synchronic关键字,但是semaphore可以控制n个线程同时访问资源。举个例子,大家都用过公共厕所吧,假设厕所有5个蹲厕,只要没人就可以进去大号。那么就可以用semaphore模拟公共厕所大号的逻辑。注:这是一段有味道的代码。

public class SemaphoreTest {

    // 厕所有5个蹲厕,全部占满就得等待
    private static final Semaphore wc = new Semaphore(5);

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            // 假设有100个人要同时使用厕所
            new ShitThread().start();
        }
    }

    /**
     * 大号线程
     */
    static class ShitThread extends Thread {

        @Override
        public void run() {
            try {
                wc.acquire();
                System.out.println(getName() + "开始大号");
                Thread.sleep(5000); // 假设消耗5s,你也可以给个随机数
                System.out.println(getName() + "结束大号");
                wc.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值