-
CountnDownLatch表示计数器,可以在构造方法中传入初始化的计数值,当一个线程调用它的await()方法将会阻塞,其他线程调用countDown()方法,对CountDownLatch中的数字减少一,当数字为0是,所有被阻塞的线程都将被唤醒。
-
底层实现的原理就是调用await()方法的时候会利用AQS进行排队,一旦数字为0,将会从AQS中排队的线程依次唤醒
-
public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 0; i < 6; i++) { new Thread(() -> { try { Random random = new Random(); // 模拟业务执行时间 Thread.sleep(random.nextInt(6000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("当前线程:"+Thread.currentThread().getName()); countDownLatch.countDown(); }).start(); } try { countDownLatch.await(); System.out.println("终于轮到我执行了"); } catch (InterruptedException e) { e.printStackTrace(); } }
-
-
Semaphore表示信号量,表示同时允许最多多少个线程使用该信号量,通过acquire()方法来获取许可,如果没有许可可用则线程阻塞,并通过AQS来排队,通过release()方法来释放许可,当某个线程释放许可的时候,会从AQS中排队的线程依次唤醒
-
public static void main(String[] args) { // 一共只有一个车位 Semaphore semaphore = new Semaphore(1); for (int i = 0; i < 3; i++) { new Thread(() -> { try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("当前线程抢到车位:"+Thread.currentThread().getName()); Random random = new Random(); try { Thread.sleep(random.nextInt(6000)); } catch (InterruptedException e) { e.printStackTrace(); } semaphore.release(); System.out.println("当前线程离开车位:"+Thread.currentThread().getName()); }).start(); } }
-
-
CyclicBarrier表示线程屏障,让一组线程到达一个屏障点的时候进行阻塞,直到最后一个线程到达屏障点,屏障barrier才会释放,线程进入屏障使用await()方法
-
public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> System.out.println("终于等到我执行了")); for (int i = 0; i < 7; i++) { new Thread(() -> { Random random = new Random(); try { Thread.sleep(random.nextInt(6000)); System.out.println("当前任务执行完成:" + Thread.currentThread().getName()); try { cyclicBarrier.await(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } }
-
Q.E.D.