前入式JUC常用类源码分析

前入式JUC常用类源码分析本文详细介绍了 Java 并发编程中三种重要的同步工具 CountDownLat 用于线程间等待计数器到达零 Semaphore 控制同时访问资源的线程数量 CyclicBarrie 使一组线程达到屏障后统一继续执行

大家好,欢迎来到IT知识分享网。

CountDownLatch
public class CountDownDemo { 
    / * countdown倒计时的意思;允许一个或者多个线程被阻塞,等待其他线程执行完在被唤醒,有点类似join * 应用场景:可以用来控制并发量,在某个条件之后实现秒杀 * @param args */ public static void main(String[] args) throws InterruptedException { 
    CountDownLatch countDownLatch = new CountDownLatch(3); //3-1 new Thread(countDownLatch::countDown).start(); //2-1 new Thread(countDownLatch::countDown).start(); //1-1=0 new Thread(countDownLatch::countDown).start(); countDownLatch.await(); //等待countdown次数被减完,再去唤醒主线程 System.out.println("主线程执行完~"); } } 

下面简单展示一下秒杀操作

public class MyCountDownLatch implements Runnable { 
    static CountDownLatch countDownLatch = new CountDownLatch(1); public static void main(String[] args) { 
    for (int i = 0; i < 100; i++) { 
    new Thread(new MyCountDownLatch(), "myCountDownThread" + i).start(); } System.out.println("2秒后执行秒杀操作吧!"+ System.currentTimeMillis()); try { 
    TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { 
    e.printStackTrace(); } countDownLatch.countDown(); } @Override public void run() { 
    try { 
    countDownLatch.await(); System.out.println("wait for countDownLatch: " + System.currentTimeMillis()); } catch (InterruptedException e) { 
    e.printStackTrace(); } } } // print result 2秒后执行秒杀操作吧!55 wait for countDownLatch: 56 wait for countDownLatch: 56 wait for countDownLatch: 56 wait for countDownLatch: 56 wait for countDownLatch: 56 wait for countDownLatch: 56 wait for countDownLatch: 56 wait for countDownLatch: 56 ... // 大概看了90%的误差在1ms 

那光会用还远远不够啊,接下来我们到胃深入一下看看
在这里插入图片描述
countDownLatch先到这里

Semaphore

顾名思义就是我们停车场的信号灯,可以控制同时可以访问的线程数,类似限流的作用

public class MySemaphore { 
    static Semaphore semaphore = new Semaphore(5); public static void main(String[] args) { 
    for (int i = 0; i < 20; i++) { 
    new Thread(new Car(i, semaphore)).start(); } } static class Car implements Runnable{ 
    private Integer carId; private Semaphore carSemaphore; public Car(Integer carId, Semaphore semaphore) { 
    this.carId = carId; this.carSemaphore = semaphore; } @Override public void run() { 
    try { 
    carSemaphore.acquire(); System.out.println("第"+carId+"辆车进来了"); TimeUnit.SECONDS.sleep(4); System.out.println("第"+carId+"辆车走了"); carSemaphore.release(); } catch (InterruptedException e) { 
    e.printStackTrace(); } } } } // print result0辆车进来了 第3辆车进来了 第2辆车进来了 第1辆车进来了 第5辆车进来了 第5辆车走了 第3辆车走了 第2辆车走了 第4辆车进来了 第7辆车进来了 第0辆车走了 第1辆车走了 第8辆车进来了 第6辆车进来了 第11辆车进来了 // 停车场最多停5辆车11辆车走了 第4辆车走了 第9辆车进来了 第7辆车走了 第6辆车走了 第13辆车进来了 第8辆车走了 第14辆车进来了 第12辆车进来了 第10辆车进来了 第14辆车走了 第9辆车走了 第10辆车走了 第12辆车走了 第13辆车走了 

用力深入进去发现又有AQS不愧是并发的核心啊
在这里插入图片描述

CyclicBarrier

表面上看起来是一个可循坏使用的屏障,线程到达屏障会被阻塞直到,一组线程全部到达屏障时候才会继续工作

public class MyCyclicBarrier implements Runnable{ 
    @Override public void run() { 
    System.out.println("最后进行筛选处理"); } public static void main(String[] args) { 
    CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new MyCyclicBarrier()); new TestThread("my girl1", cyclicBarrier).start(); new TestThread("my girl2", cyclicBarrier).start(); new TestThread("my girl3", cyclicBarrier).start(); new TestThread("my girl4", cyclicBarrier).start(); } static class TestThread extends Thread{ 
    private String name; private CyclicBarrier cb; public TestThread(String name, CyclicBarrier cb) { 
    this.name = name; this.cb = cb; } @Override public void run() { 
    try { 
    System.out.println(name); cb.await(); } catch (InterruptedException | BrokenBarrierException e) { 
    e.printStackTrace(); } } } } // print result my girl1 my girl4 my girl3 my girl2 最后进行筛选处理 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/143660.html

(0)
上一篇 2025-05-01 22:15
下一篇 2025-05-01 22:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信