乐趣区

关于多线程:JAVA并发编程CountDownLatchCyclicBarrierSemaphore

1.CountDownLatch 根底概念和应用

2.CyclicBarrier 根底概念和应用

3.Semaphore 根底概念和应用

1.CountDownLatch 根底概念和应用
艰深的来说,CountDownLatch 的性能就是让一些线程期待直到另外的一些线程全副运行完结之后,再开始运行
举个例子:
一个教室每天都要安顿一个同学值日关门,这个同学肯定要等到其他同学全副来到之后(期待其它线程全副执行结束 ),能力把门关上( 才会往下执行)。

咱们用代码来证实一下上述的例子:

首先,咱们要用到三个重要的办法:

// 构造方法的数字示意,要等五个线程运行结束后,才会持续往下执行
CountDownLatch countDownLatch = new CountDownLatch(5);
// 须要期待的线程减一(相当于一个同学来到了老师)countDownLatch.countDown();
// 期待其它所有线程执行结束,再往下执行(再往下执行关门动作)countDownLatch.await();
    CountDownLatch countDownLatch = new CountDownLatch(5);

        for (int i = 1; i <= 5; i++) {new Thread(() -> {System.out.println("第" + Thread.currentThread().getName() + "个同学来到教室");
                // 一个同学来到后,须要期待的线程就减一
                countDownLatch.countDown();}, i + "").start();}

        // 到这儿期待
        countDownLatch.await();

        new Thread(() -> {System.out.println("班长来到教室");
        }).start();

执行后果为:

能够看出,countDownLatch 期待其它线程执行结束做的是减法操作。

2.CyclicBarrier 根底概念和应用
如果说 countDownLatch 是做减法,CyclicBarrier 就是做加法。
举个例子:集齐七颗龙珠号召神龙!(期待七个线程运行结束,而后执行最终的线程。)

同样地咱们要用到两个办法:

        // 构造函数能够传指定线程的数量,以及线程数量达到后的实现办法,可用 lambda 表达式实现。CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {System.out.println("号召神龙!");
        });
        // 当一个线程执行结束后,调用这个办法示意曾经执行的线程 +1(已收集的龙珠 +1)cyclicBarrier.await();

咱们将举例用代码实现一次:

       // 设置期待的线程总数和实现之后的办法内容
       CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {System.out.println("号召神龙!");
        });

        for (int i = 1; i <= 7; i++) {
            final int num = i;
            new Thread(() -> {System.out.println(Thread.currentThread().getName() + "收集到第" + num + "颗龙珠");
                try {
                   // 实现线程数 +1
                    cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();
                } catch (BrokenBarrierException e) {e.printStackTrace();
                }
            }, i + "").start();}

运行后果为:

能够得出,CyclicBarrier 是一个 做加法 的操作,线程减少到肯定水平,就能够执行最终的线程。(就如同人到齐了再散会。)

3.Semaphore 根底概念和应用
Semaphore 是一种信号量,咱们能够用“抢车位”来形容这个类,就像多辆车竞争多个车位。(多个线程争抢多个资源。)

咱们依然用代码来实现下面的举例:

// 一共有三个资源
Semaphore semaphonre = new Semaphore(3);
// 取得资源
semaphonre.acquire();
// 开释资源
semaphonre.release();
        Semaphore semaphonre = new Semaphore(3);

        for (int i = 1; i <= 5; i++) {
            final int temp = i;
            new Thread(() -> {
                try {semaphonre.acquire();
                    System.out.println("第" + temp + "辆车进入停车位");
                    Thread.sleep(3000);
                    System.out.println("第" + temp + "辆车,停车 3 秒后来到车位");
                } catch (InterruptedException e) {e.printStackTrace();
                } finally {semaphonre.release();
                }

            }, i + "").start();}

运行后果为:

能够看出,每次最多只能有三个停车位进入,否则就阻塞。

总结:
CountDownLatch:做减法,当计数器变为 0 的时候,调用 await 的线程会被唤醒,继续执行。
CyclicBarrier:做加法,等到肯定数量的线程执行,再继续执行最终的办法。
Semaphore:多个线程争抢多个资源。

退出移动版