CountDownLatch和CyclicBarrier的主要联系和区别如下:
1.闭锁CountDownLatch做减计数,而栅栏CyclicBarrier则是加计数。
2.CountDownLatch是一次性的,CyclicBarrier可以重用。
3.CountDownLatch强调一个线程等多个线程完成某件事情。CyclicBarrier是多个线程互等,等大家都完成。
4.鉴于上面的描述,CyclicBarrier在一些场景中可以替代CountDownLatch实现类似的功能。
另外,值得一提的是,CountDownLatch和CyclicBarrier在创建和启动线程时,都没有明确提到同时启动全部线程,事实上这在技术上是不大可能,不必要,不提倡的。
先看例子一:
class SubRunnable implements Runnable {
private CountDownLatch begin, end;
private List<Integer> sublist;
public SubRunnable(List<Integer> sublist, CountDownLatch begin,CountDownLatch end) {
this.sublist = sublist;
this.begin = begin;
this.end = end;
}
@Override
public void run() {
try {
begin.await();
if (sublist != null) {
for (int i : sublist) {
System.out.println("线程" + Thread.currentThread().getName() + ", i = " + i);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
System.out.println(System.currentTimeMillis() + ",线程" + Thread.currentThread().getName() + ",开始执行!");
end.countDown();
}
}
}
public class BatchWithCountDownLatch {
private static final int MAX = 3;
private static void list(List<Integer> list) {
if(list == null){
list = new ArrayList<Integer>();
}
for(int i = 0 ;i < 1000;i++){
list.add(i);
}
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list(list);
//把list拆分成多个
int mod = list.size() % MAX;
int threadCount = mod == 0 ? list.size() / MAX : list.size() / MAX + 1;
ExecutorService executors = Executors.newFixedThreadPool(threadCount);
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(threadCount);
for(int i = 0; i< threadCount;i++){
int subsize = (i + 1) * MAX;
executors.execute(new SubRunnable(list.subList(i * MAX, subsize > list.size() ? list.size() : subsize),begin,end));
}
System.out.println("开始 !");
begin.countDown();
long startTime = System.currentTimeMillis();
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("线程" + Thread.currentThread().getName() + "," + System.currentTimeMillis() + ", 所有线程已完成,开始进入下一步!");
System.out.println("花费时间 -> " + (System.currentTimeMillis() - startTime) + " ms");
}
System.out.println("开始进入第二步操作! ");
System.out.println("end! ");
}
}
这是根据jdk文档中的伪代码例程,编写的一个例子,我们完全可以将这个例程改为只使用一个CountDownLatch来实现之。经过测试,发现begin的引入对程序基本无用,当list是1000的数量级时,最先启动的线程仍然比最后启动的快几十毫秒左右;而不设置begin开始闭锁的程序,也是完全一样的情况。
例子二:
class SubRunnable implements Runnable {
private CyclicBarrier cyclicBarrier;
private List<Integer> sublist;
public SubRunnable(List<Integer> sublist, CyclicBarrier cyclicBarrier) {
this.sublist = sublist;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
System.out.println(System.currentTimeMillis() + ",线程" + Thread.currentThread().getName() + ",开始执行!");
if(sublist != null){
for(int i : sublist){
System.out.println("线程" + Thread.currentThread().getName() + ", i = " + i);
}
}
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class ReplaceCountDownLatch {
private static final int MAX = 3;
private static void list(List<Integer> list) {
if(list == null){
list = new ArrayList<Integer>();
}
for(int i = 0 ;i < 10;i++){
list.add(i);
}
}
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
List<Integer> list = new ArrayList<Integer>();
list(list);
//把list拆分成多个
int mod = list.size() % MAX;
int threadCount = mod == 0 ? list.size() / MAX : list.size() / MAX + 1;
ExecutorService executors = Executors.newFixedThreadPool(threadCount);
final CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount,new Runnable() {
@Override
public void run() {
//根据jdkdoc里的描述,哪个线程最后运行完,就执行下面的代码。
System.out.println("线程" + Thread.currentThread().getName() + "," + System.currentTimeMillis() + ", 所有线程已完成,开始进入下一步!");
}
});
for(int i = 0; i< threadCount;i++){
int subsize = (i + 1) * MAX;
executors.execute(new SubRunnable(list.subList(i * MAX, subsize > list.size() ? list.size() : subsize),cyclicBarrier));
}
cyclicBarrier.await();
executors.shutdown();
System.out.println("开始进入第二步操作! ");
System.out.println("end! ");
}
}
使用栅栏CyclicBarrier实现和上面闭锁CountDownLatch相同的功能。
分享到:
相关推荐
《java并发编程》中CountDownLatch和CyclicBarrier用法实例大全,几乎包含了所有重要的用法
java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf
java并发编程中CountDownLatch和CyclicBarrier的使用.pdf
CountDownLatch 和 CyclicBarrier 为线程同步的辅助工具,通过它可以做到使一条线程一直阻塞等待,直到其他线程完成其所处理的任务。
12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore 16. 执行器服务 ExecutorService 17. 线程池执行者 ThreadPoolExecutor 18. 定时执行者服务 ScheduledExecutorService ...
主要介绍了详解java CountDownLatch和CyclicBarrier在内部实现和场景上的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用 CountDownLatch、CyclicBarrier、Semaphore这些线程协作工具类是基于AQS的,看完这篇博客后可以去看下面这篇博客,了解它们是如何实现的。 Java并发...
java 高并发应用场景
12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore 16. 执行器服务 ExecutorService 17. 线程池执行者 ThreadPoolExecutor 18. 定时执行者服务 ScheduledExecutorService ...
闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore 16. 执行器服务 ExecutorService 17. 线程池执行者 ThreadPoolExecutor 18. 定时执行者服务 ScheduledExecutorService 19....
主要介绍了Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解的相关资料,需要的朋友可以参考下
mybaits 多线程 实现数据批量插入 (运用CountDownLatch实现闭锁) 1、mybatis批处理 2、数据分批量查询 3、数据分批量插入
12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore 16. 执行器服务 ExecutorService 17. 线程池执行者 ThreadPoolExecutor 18. 定时执行者服务 ScheduledExecutorService ...
CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程...
目录线程安全 Thread Safety重入锁 ReentrantLock读写锁 ReadWriteLock倒计数器 CountDownLatch循环栅栏 CyclicBarrier信号量 Semaphore 线程安全 Thread Safety JMM JMM(Java Memory Model)是一种基于计算机内存...
12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore 16. 执行器服务 ExecutorService 17. 线程池执行者 ThreadPoolExecutor 18. 定时执行者服务 ScheduledExecutorService ...
与CountDownLatch不同的是,CyclicBarrier可以重复使用,即当所有线程都到达屏障后,屏障会自动重置,可以继续使用。 CyclicBarrier的构造方法如下: java public CyclicBarrier(int parties, Runnable ...
在我们JDK的并发包中,提供了几个非常有用的并发工具类,比如:CountDownLatch 闭锁、CyclicBarrier 同步屏障、Semaphore 信号量,在线程之间交换数据的一种方式 Exchanger,赶紧操练起来。 2、CountDownLatch 闭锁 ...