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:多个线程争抢多个资源。