`

CountDownLatch、CyclicBarrier 和 Semaphore原理分析

阅读更多
Java 中常用的并发工具有 CountDownLatch、CyclicBarrier 和 Semaphore.

1.CountDownLatch 等待所线程完成.

比如说,我将一个计算任务拆分成多个任务,然后多个线程分别计算,最后等所有任务计算完成后,在继续执行.

其实还有一个思路可以实现该功能,join. 但是 join 方法是有局限的,join 方法用于当前执行线程等待 join 线程执行结束,其实现原理是
不停的检查 join 线程是否存货,如果 join 线程存货,则让当前线程永远等待.

现在来看下 CountDownLatch 的实现原理.

CountDownLatch 的实现思路很巧妙,一开始就将 state 设置为非 0(代表该线程被阻塞),每次调用 countDown 释放锁,当最终 state = 0
时,说明可以申请到锁了,则主线程执行.

如果没有申请到锁怎么处理了?该线程可能先自旋一会,最终调用 LockSupport.park 方法自我阻塞.

2.CyclicBarrier 同步屏障

CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到所有线程都到达某个公共屏障点(也可以叫同步点),
即相互等待的线程都完成调用await方法,所有被屏障拦截的线程才会继续运行await方法后面的程序。
在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。
因为该屏障点在释放等待线程后可以重用,所以称它为循环的屏障点。CyclicBarrier支持一个可选的Runnable命令,
在一组线程中的最后一个线程到达屏障点之后(但在释放所有线程之前),该命令只在所有线程到达屏障点之后运行一次,
并且该命令由最后一个进入屏障点的线程执行.

3.CyclicBarrier 的应用场景

CyclicBarrier 可以用于多线程计算数据,最终合并计算结果的场景.

原理:CyclicBarrier 有栅栏的意思,比如说有三个线程执行,线程A执行较快,它执行完了,要等线程B和线程C. 等这三个线程都执行完后,这个
栅栏才打开放行,这三个线程继续执行,如何实现的了?

每个线程执行 await 方法,count--. 然后使用 condition await 等待. 等 count 为 0 时,开始放行. 设计的很精妙.


4.CountDownLatch 和 CyclicBarrier 的区别

CountDownLatch 只能使用一次,而 CyclicBarrier 可以使用多次.

CountDownLatch 和 CyclicBarrier 的语义不好区分,但是仔细品味下还是能发现一些区别的. CountDownLatch 是说其他线程就绪后,主线程
开始执行,而 CyclicBarrier 比如说公司团建,现在在大巴车那等,先到得人要等后到的人到齐后,大巴车才发车去目的地(Runnable),然后公司员工可以干
其他活,例如乒乓球比赛等.

5.Semaphore
Semaphore 是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保障合理的使用公共资源.

实现:
Semaphore 是如何做到对某一物理或逻辑资源访问数量的限制了?


答案是 AQS.


比如我定义:Semaphore(10), 同一时刻只能有 10 个线程访问线程池,每来一个线程,state -1,当第11线程访问的结果是啥了?
由于 state < 0 而被阻塞.


当一个线程访问完后,调用 release 方法,state + 1. 然后唤醒等待访问线程池的线程.


注意:


由于 release 方法中,没有对 state < 0 进行判断,每调用一次 release 方法 state + 1.
也就是说:虽然我定义的 state = 10. 但是我调用 11 次 release 方法,那么此时 state = 11.这就完成了
Semaphore 的动态增长.
如果说我觉得10个线程同时访问线程池,线程池扛不住了,我要减少同时访问的数量,该怎么办了?继承 Semaphore 类,
重写 reducePermits 方法就好了.


Semaphore 和 CountDownLatch 对比分析


CountDownLatch 是为了共同干一件事,线程1完成A部分,线程2完成B部分,线程3完成C部分. 而 Semaphore 是为了限制同一时间对
某一资源访问的数量, 例如:同一时间只允许10个线程同时访问.

6.线程间交换数据 Exchanger

Exchanger 提供了一个同步点,两个线程可以交换彼此的数据,如果第一个线程先执行 exchange() 方法,它会一直等待第二个线程也执行
exchange() 方法,当两个线程都达到同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方.



1
0
分享到:
评论

相关推荐

    CountDownLatch、CyclicBarrier、Semaphore.md

    java 高并发应用场景

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解 Java并发编程是Java语言中的一种高级技术,用于处理多线程编程中的同步问题。Java 1.5中引入了几个高效的辅助类,包括CountDownLatch、...

    Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用

    理解它们的工作原理和使用场景,对于编写高并发、高性能的Java应用程序至关重要。在实际使用中,根据具体需求选择合适的方法,如CountDownLatch适用于一个线程等待多个线程的场景,CyclicBarrier适合多个线程协作...

    CountDownLatch 和 CyclicBarrier 的运用(含AQS详解)

    ### CountDownLatch 和 CyclicBarrier 的运用(含AQS详解) #### CountDownLatch **定义与特点:** CountDownLatch 是 Java 并...通过了解它们的实现原理和应用场景,开发者可以更好地选择合适的工具来满足自己的需求。

    CountDownLatch、Semaphore等4大并发工具类详解

    本文将详细介绍 Java 并发工具类的四大类:CountDownLatch、Semaphore、CyclicBarrier 和 Phaser,及其应用场景和使用方法。 CountDownLatch CountDownLatch 是一个同步的辅助类,允许一个或多个线程,等待其他一...

    JUC面试知识点手册快速版

    4.1 CountDownLatch 4.2 CyclicBarrier 4.3 Semaphore 4.4 Exchanger 第五章:原子类和无锁编程 5.1 AtomicInteger与AtomicLong 5.2 AtomicReference 第六章:线程池及其应用 6.1 ThreadPoolExecutor 6.2...

    Java并发编程-3.pdf

    CountDownLatch、CyclicBarrier 和 Semaphore 等多线程协作机制都是 Java 并发编程中的重要组成部分。它们可以帮助开发者编写高效、可靠的多线程程序,解决复杂的并发问题。 在实际开发中,我们可以根据具体情况...

    ThreadTest.rar

    java并发,主要用于初学者学习,主要案列,Thread.join,ThreadLocal,Lock接口,LockSupport,Condition接口,ConcurrentHashMap的实现原理与...Fork/Join 框架,CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    java并发编程面试题分享给需要的同学.docx

    CountDownLatch CyclicBarrier Semaphore 什么是自旋锁(CAS,compare and swap)? CAS存在的问题 什么是读写锁? 谈谈并发编程三要素 简述Java内存模型(JMM) volatile关键字知道么,它是怎么实现的?(难点 重要) ...

    concurrent-1.3.4.jar

    同步工具类:concurrent包提供了一些同步工具类,如CountDownLatch、CyclicBarrier、Semaphore等,可以帮助开发者实现复杂的线程协作和同步任务。 并发集合类:concurrent包提供了一些并发集合类,如...

    java并发变成实战

    CountDownLatch、CyclicBarrier和Semaphore是典型的同步工具,用于协调多个线程间的操作顺序。 此外,书中还会详细讨论Java内存模型(JMM)和volatile关键字。Java内存模型规定了线程之间如何共享数据,volatile...

    线程实例(并发库引入到Java标准库 )

    有以下类的实例: ThreadPool ScheduledThread CyclicBarrier BlockingQueue CountDownLatch FutureTask CompletionService Semaphore

    CountDownLatch练习

    如果需要一部分线程完成即可继续,可以选择CyclicBarrier或Semaphore。 在实际编程中,熟练掌握CountDownLatch可以帮助我们更有效地编写高并发程序,解决复杂的同步问题。通过阅读和理解提供的代码样例(如`...

    多线程控制的三大安全类封装

    多线程控制的三大安全类:CountDownLatch、CyclicBarrier、Semaphore,这工具包将其封装,可以让初学者更容易学习以及让开发者更容易调用,不需要自己重新编写核心代码。具体事例在源码中。

    常见的Java笔试题-JVM-JUC-Core:JUCJVM核心知识点

    CountDownLatch/CyclicBarrier/Semaphore CountDownLatch 枚举类的使用 CyclicBarrier Semaphore 阻塞队列 SynchronousQueue Callable接口 阻塞队列的应用——生产者消费者 传统模式 阻塞队列模式 阻塞队列的应用...

    Java并发包源码分析(JDK1.8)

    AQS相关应用(CountDownLatch、CyclicBarrier、Semaphore等),executor(ThreadPoolExecutor、ScheduledThreadPoolExecutor、FutureTask等),collection(ConcurrentHashMap、CopyOnWriteArrayList等), ...

    countdownlatch-example-sourcecode.zip

    如果需要重复使用,考虑使用CyclicBarrier或Semaphore等其他同步工具。 - 误用可能导致死锁,比如计数器设置过大或者`countDown()`未正确调用,可能会导致等待的线程永久阻塞。 通过对`countdownlatch-example-...

    java面试题,内容详细,包含mysql,多线程,中间件

    面试者还应熟悉并发容器(如ConcurrentHashMap和CopyOnWriteArrayList)以及并发工具类(如CountDownLatch、CyclicBarrier和Semaphore)。 最后,中间件是Java面试中的另一个重要领域,它涉及到应用程序之间的通信...

    java.util.concurrent 测试源文件

    6. **并发工具类**:如CountDownLatch、CyclicBarrier、Semaphore等,用于协调多线程间的同步。例如,CountDownLatch常用于等待一组线程完成;CyclicBarrier允许一组线程到达一个屏障时暂停,直到所有线程都到达;...

Global site tag (gtag.js) - Google Analytics