Java CountDownLatch与CyclicBarrier及Semaphore使用教程
欲无缘 人气:0CountDownLatch
CountDownLatch是一个倒数的计数器阀门,初始化时阀门关闭,指定计数的数量,当数量倒数减到0时阀门打开,被阻塞线程被唤醒。
public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { // 总数是6,必须要执行任务的时候,再使用 ! CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 1; i <=6 ; i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName()+" Go out"); countDownLatch.countDown(); // 数量-1 },String.valueOf(i)).start(); } countDownLatch.await(); // 等待计数器归零,然后再向下执行 System.out.println("Close Door"); } }
原理
countDownLatch.countDown();//数量-1
countDownLatch.await();//等待
每次有线程调用 countDown() 数量-1,假设计数器变为0,countDownLatch.await() 就会被唤醒,继续执行!
CyclicBarrier
CyclicBarrier是一个可循环的屏障,它允许多个线程在执行完相应的操作后彼此等待共同到达一个point,等所有线程都到达后再继续执行。
CyclicBarrier也可以像CountDownLatch一样适用于多个子任务并发执行,当所有子任务都执行完后再继续接下来的工作。
public class CyclicBarrierDemo { public static void main(String[] args) { // 召唤龙珠的线程 CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{ System.out.println("召唤神龙成功!"); }); for (int i = 1; i <=7 ; i++) { final int temp = i; // lambda能操作到 i 吗 new Thread(()->{ System.out.println(Thread.currentThread().getName()+"收集"+temp+"个龙珠"); try { cyclicBarrier.await(); // 等待 } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } }
Semaphore
Semaphore翻译过来是信号量的意思,它的作用是控制多个线程对同一个资源的访问线程数量。比如在停车场停车,里面有10个车位,当这10个车位被停满的时候其他的车只能等待(堵塞)里面有车驶出(release)然后再进入。
public class SemaphoreDemo { public static void main(String[] args) { // 线程数量:停车位! 限流! Semaphore semaphore = new Semaphore(3); for (int i = 1; i <=6 ; i++) { new Thread(()->{ // acquire() 得到 try { semaphore.acquire(); System.out.println(Thread.currentThread().getName()+"抢到车位"); TimeUnit.SECONDS.sleep(2); System.out.println(Thread.currentThread().getName()+"离开车位"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); // release() 释放 } },String.valueOf(i)).start(); } } }
semaphore.acquire();
获得,假设如果已经满了,等待,等待被释放为止!
semaphore.release();
释放,会将当前的信号量释放 + 1,然后唤醒等待的线程!
作用: 多个共享资源互斥的使用!并发限流,控制最大的线程数!
加载全部内容