最新公告
  • 新注册用户请前往个人中心绑定邮箱以便接收相关凭证邮件!!!点击前往个人中心
  • Java并发(七)J.U.C – AQS

    java.util.concurrent(J.U.C)大大提高了并发性能,AQS 被认为是 J.U.C 的核心。

    CountdownLatch

    用来控制一个线程等待多个线程。

    维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些因为调用 await() 方法而在等待的线程就会被唤醒。

    public class CountdownLatchExample {
    
        public static void main(String[] args) throws InterruptedException {
            final int totalTread = 10;
            CountDownLatch countDownLatch = new CountDownLatch(totalTread);
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < totalTread; i++) {
                executorService.execute(() -> {
                    System.out.print("run..");
                    countDownLatch.countDown();
                });
            }
            countDownLatch.await();
            System.out.println("end");
            executorService.shutdown();
        }
    }
    
    run..run..run..run..run..run..run..run..run..run..end
    

    CyclicBarrier

    用来控制多个线程互相等待,只有当多个线程都到达时,这些线程才会继续执行。

    和 CountdownLatch 相似,都是通过维护计数器来实现的。但是它的计数器是递增的,每次执行 await() 方法之后,计数器会加 1,直到计数器的值和设置的值相等,等待的所有线程才会继续执行。和 CountdownLatch 的另一个区别是,CyclicBarrier 的计数器可以循环使用,所以它才叫做循环屏障。

    下图应该从下往上看才正确。

    public class CyclicBarrierExample {
    
        public static void main(String[] args) throws InterruptedException {
            final int totalTread = 10;
            CyclicBarrier cyclicBarrier = new CyclicBarrier(totalTread);
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < totalTread; i++) {
                executorService.execute(() -> {
                    System.out.print("before..");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.print("after..");
                });
            }
            executorService.shutdown();
        }
    }
    
    before..before..before..before..before..before..before..before..before..before..after..after..after..after..after..after..after..after..after..after..
    

    Semaphore

    Semaphore 就是操作系统中的信号量,可以控制对互斥资源的访问线程数。

    以下代码模拟了对某个服务的并发请求,每次只能有 3 个客户端同时访问,请求总数为 10。

    public class SemaphoreExample {
        public static void main(String[] args) {
            final int clientCount = 3;
            final int totalRequestCount = 10;
            Semaphore semaphore = new Semaphore(clientCount);
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < totalRequestCount; i++) {
                executorService.execute(()->{
                    try {
                        semaphore.acquire();
                        System.out.print(semaphore.availablePermits() + " ");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        semaphore.release();
                    }
                });
            }
            executorService.shutdown();
        }
    }
    
    2 1 2 2 2 2 2 1 2 2
    
    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » Java并发(七)J.U.C – AQS

    常见问题FAQ

    如果资源链接失效了怎么办?
    本站用户分享的所有资源都有自动备份机制,如果资源链接失效,请联系本站客服QQ:2580505920更新资源地址。
    如果用户分享的资源与描述不符怎么办?
    可以联系客服QQ:2580505920,如果要求合理可以安排退款或者退赞助积分。
    如何分享个人资源获取赞助积分或其他奖励?
    本站用户可以分享自己的资源,但是必须保证资源没有侵权行为。点击个人中心,根据操作填写并上传即可。资源所获收益完全归属上传者,每周可申请提现一次。
    如果您发现了本资源有侵权行为怎么办?
    及时联系客服QQ:2580505920,核实予以删除。

    参与讨论

    • 155会员总数(位)
    • 3735资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 382稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多
    成为赞助用户享有更多特权立即升级