笔记E《CountDownLatchCyclicBarrierSemaphore》

    技术2024-05-24  83

    文章目录

    CountDownLatchCyclicBarrierSemaphore

    CountDownLatch

    让一些线程阻塞直到另外一些完成后才被唤醒。

    CountDownLatch 主要有两个方法,当一个或多个线程调用 await方法时,调用线程会被阻塞.其他线程调用 countDown 方法计数器减1(调用 countDown 方法时线程不会阻塞),当计数器的值变为0,因调用await方法被阻塞的线程会被唤醒,继续执行。

    public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(6); for(int i = 0;i< 6 ;i++){ new Thread(()->{ System.out.println(Thread.currentThread().getName()+"\t AAAAAAAAAA"); countDownLatch.countDown(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } },i+"").start(); } countDownLatch.await(); System.out.println(Thread.currentThread().getName()+"\t BBBBBBBBBBBBBB \t" + countDownLatch.getCount()); } } 0 AAAAAAAAAA 3 AAAAAAAAAA 2 AAAAAAAAAA 5 AAAAAAAAAA 1 AAAAAAAAAA 4 AAAAAAAAAA main BBBBBBBBBBBBBB 0 main 线程由于 await 处于阻塞状态,等待 countDownLatch 归零后才开始执行。

    CyclicBarrier

    CyclicBarrier 的字面意思是可循环(Cyclic) 使用的屏障(barrier)。它要做的事情是:让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过 CyclicBarrier 的 await() 方法。

    public class CyclicBarrierDemo { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{ System.out.println("召唤神龙"); }); for (int i = 0; i < 7; i++) { final int tmpInt = i; new Thread(()->{ System.out.println(Thread.currentThread().getName()+"\t"+tmpInt); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"\t完成"); },i+" 线程").start(); } } } 0 线程 0 3 线程 3 2 线程 2 1 线程 1 6 线程 6 5 线程 5 4 线程 4 # 直到 cyclicBarrier 之上的代码循环遍历完成,才进行执行下一行代码 召唤神龙 4 线程 完成 0 线程 完成 2 线程 完成 5 线程 完成 3 线程 完成 6 线程 完成 1 线程 完成 CyclicBarrier 的 await 等待其他线程执行,直到其他线程完成,当前线程才继续执行。

    Semaphore

    Semaphore信号量主要有两个目的:

    用于多个共享资源的互斥使用;用于并发数量的控制(是synchronized的加强版,当并发数量为1时就退化成synchronized);

    主要方法:

    Semaphore(int permits):构造函数,允许控制的并发数量;acquire():请求一个信号量,导致信号量的数量减1;release():释放一个信号量,信号量加1; public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore = new Semaphore(5); for (int i = 1; i <= 1000; i++) { new Thread(()->{ try { semaphore.acquire(); System.out.println(Thread.currentThread().getName() + "\t抢到车位"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "\t停车3秒后离开车位"); }catch (Exception e){ e.printStackTrace(); }finally { semaphore.release(); } },String.valueOf(i)).start(); } } } 1 抢到车位 2 抢到车位 4 抢到车位 3 抢到车位 5 抢到车位 5 停车3秒后离开车位 4 停车3秒后离开车位 1 停车3秒后离开车位 2 停车3秒后离开车位 3 停车3秒后离开车位
    Processed: 0.015, SQL: 12