1、CountDownLatch
计数器
package com.juc.ofok.demo; import java.util.concurrent.CountDownLatch; /** * 代码源于生活,高于生活 * * @author ofok * @date 2020-04-19 18:45:33 */ public class CountDownLatchDemo { /** * 有些任务是不得不阻塞的, 减法计数器 */ public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 0; i <= countDownLatch.getCount(); i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName() + " start "); // 出去一个人计数器就减 -1 countDownLatch.countDown(); }, String.valueOf(i)).start(); } // 阻塞等待计数器归零 countDownLatch.await(); // 阻塞的操作:计数器 num++ System.out.println(Thread.currentThread().getName() + " === END "); } /** * 结果诡异的嘛?达不到预期的 Main end 在最后一个 */ public static void test1() { for (int i = 1; i <= 6; i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName()+" start "); }, String.valueOf(i)).start(); } System.out.println(Thread.currentThread().getName() + " End "); } }
CountDownLatch countDownLatch = new CountDownLatch(6);
countDownLatch.countDown(); 出去一个人计数器就 -1
countDownLatch.await(); 阻塞等待计数器归零
2、CyclicBarrier 回环栅栏 计数器加法
package com.ofok.juc.demo; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * 代码源于生活,高于生活 * 回环栅栏 计数器加法 * * @author ofok * @date 2020-04-19 18:45:33 */ public class CyclicBarrierDemo { public static void main(String[] args) { // 集齐7个龙珠召唤神龙 ++ 1// // 等待cyclicBarrier计数器满,就执行后面的Runnable,不满就阻塞 CyclicBarrier cyclicBarrier = new CyclicBarrier(7, new Runnable() { @Override public void run() { System.out.println("神龙召唤成功!"); } }); for (int i = 1; i <= 7; i++) { final int temp = i; new Thread(() -> { System.out.println(Thread.currentThread().getName() + "收集了第" + temp + "颗龙珠"); try { cyclicBarrier.await(); // 等待 阻塞 } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } } }
3、信号量(信号灯)
package com.ofok.juc.demo; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * 代码源于生活,高于生活 * 信号量(信号灯) 抢车位 * * @author ofok * @date 2020-04-19 18:45:33 */ public class SemaphoreDemo { public static void main(String[] args) { // 模拟6个车,只有3个车位 // 3个位置 Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 6; i++) { new Thread(() -> { // 得到车位 try { semaphore.acquire(); // 得到 System.out.println(Thread.currentThread().getName() + "抢到了车位"); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName() + "离开了车位"); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放位置 semaphore.release(); } }, String.valueOf(i)).start(); } } }