敞开生长之旅!这是我参与「日新方案 12 月更文挑战」的第26天,点击检查活动详情

CountDownLatch

概念

CountDownLatch是一个同步东西类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。

CountDownLatch能够使一个线程在等候别的一些线程完结各自作业之后,再持续履行。运用一个计数器进行完成。计数器初始值为线程的数量。当每一个线程完结自己使命后,计数器的值就会减一。当计数器的值为0时,表示一切的线程都现已完结了使命,然后在CountDownLatch上等候的线程就能够恢复履行使命。

CountDownLatch典型用法1:某一线程在开端运转前等候n个线程履行结束。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当一个使命线程履行结束,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。一个典型运用场景便是发动一个服务时,主线程需求等候多个组件加载结束,之后再持续履行。

CountDownLatch典型用法2:完成多个线程开端履行使命的最大并行性。注意是并行性,不是并发,着重的是多个线程在某一时刻一起开端履行。相似于赛跑,将多个线程放到起点,等候发令枪响,然后一起开跑。做法是初始化一个共享的CountDownLatch(1),将其计数器初始化为1,多个线程在开端履行使命前首要 coundownlatch.await(),当主线程调用 countDown() 时,计数器变为0,多个线程一起被唤醒。

JUC之强大的辅助类

JUC之强大的辅助类

运用

首要运用new CountDownLatch(int count)结构出一个给定值的计数器。接着运用countDown()将计数器的值减一,而await()是时调用的线程被堵塞等候直到计数器的值为0停止。

JUC之强大的辅助类

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"\t上完自习,脱离教室");
                countDownLatch.countDown();//减一
            },String.valueOf(i)).start();
        }
        countDownLatch.await();//使当时线程等候直到锁存器计数到零停止
        System.out.println(Thread.currentThread().getName()+"\t班长关门走人");
    }
}

运转检查作用~

JUC之强大的辅助类

CountDownLatch是一次性的,计数器的值只能在结构办法中初始化一次,之后没有任何机制再次对其设置值,当CountDownLatch运用结束后,它不能再次被运用

CyclicBarrier

概念

现实生活中咱们经常会遇到这样的情形,在进行某个活动前需求等候人全部都齐了才开端。例如吃饭时要等全家人都上座了才动筷子,旅游时要等全部人都到齐了才出发,竞赛时要等运动员都上场后才开端。

在JUC包中为咱们供给了一个同步东西类能够很好的模仿这类场景,它便是CyclicBarrier类。利用CyclicBarrier类能够完成一组线程彼此等候,当一切线程都抵达某个屏障点后再进行后续的操作。下图演示了这一过程。

JUC之强大的辅助类

JUC之强大的辅助类

CyclicBarrier的字面意思是可循环(Cyclic) 运用的屏障(barrier).它要做的工作是,让一组线程抵达一个屏障(也能够叫做同步点)时被堵塞,知道最后一个线程抵达屏障时,屏障才会开门,一切被屏障阻拦的线程才会持续干活,线程进入屏障通过CyclicBarrier的await()办法.

JUC之强大的辅助类

JUC之强大的辅助类

JUC之强大的辅助类

案例

招集7颗龙珠呼唤线程。

JUC之强大的辅助类

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        //CyclicBarrier(int parties, Runnable barrierAction)
        CyclicBarrier cyclicBarrier = new  CyclicBarrier(7,()->{
            System.out.println("呼唤神龙");
        });
        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"\t收集到第"+temp+"颗龙珠");
                try {
                    //先到了等着
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

CyclicBarrier与CountDownLatch的差异

至此咱们不免会将CyclicBarrier与CountDownLatch进行一番比较。这两个类都能够完成一组线程在抵达某个条件之前进行等候,它们内部都有一个计数器,当计数器的值不断的减为0的时分一切堵塞的线程将会被唤醒。

有差异的是CyclicBarrier的计数器由自己控制,而CountDownLatch的计数器则由运用者来控制,在CyclicBarrier中线程调用await办法不只会将自己堵塞还会将计数器减1,而在CountDownLatch中线程调用await办法只是将自己堵塞而不会减少计数器的值。

别的,CountDownLatch只能阻拦一轮,而CyclicBarrier能够完成循环阻拦。一般来说用CyclicBarrier能够完成CountDownLatch的功用,而反之则不能,例如上面的赛马程序就只能运用CyclicBarrier来完成。总归,这两个类的异同点大致如此,至于何时运用CyclicBarrier,何时运用CountDownLatch,还需求读者自己去拿捏。

除此之外,CyclicBarrier还供给了:resert()、getNumberWaiting()、isBroken()等比较有用的办法。

Semaphore

概念

Semaphore信号量主要用于两个意图,一个是用于多个共享资源的互斥运用。另一个用于并发线程数的控制,用于做限流处理

JUC之强大的辅助类

JUC之强大的辅助类

Seamphore结构办法和ReentrantLock结构办法相似。默许非公正锁,为ture公正锁。

JUC之强大的辅助类

JUC之强大的辅助类

案例

6两轿车抢3个停车位,当3个停车位满时,剩下的三辆车只能走一辆停一辆。

JUC之强大的辅助类

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抢到车位");
                    //停3秒
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName() + "\t停车三秒后脱离车位");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();//开释
                }
            }, String.valueOf(i)).start();
        }
    }
}

JUC之强大的辅助类