`
Donald_Draper
  • 浏览: 980913 次
社区版块
存档分类
最新评论

CyclicBarrier使用实例

    博客分类:
  • JUC
阅读更多
CountDownLatch详解:http://donald-draper.iteye.com/blog/2360597
CountDownLatch是一次性的,CyclicBarrier正好可以循环使用。它允许一组线程互相等待,直到到达某个公共屏障点(common barrier point)。所谓屏障点就是一组任务执行完毕的时刻。下面我们来看一个实例:
package juc.latch;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
 * 测试CyclicBarrier
 * @author donald
 * 2017年3月6日
 * 下午12:52:10
 */
public class TestCyclicBarrier {
	final CyclicBarrier barrier;//屏障锁
	final int MAX_TASK;//屏障锁可共享数
	/**
	 * 
	 * @param cnt
	 */
	public TestCyclicBarrier(int cnt) {
		//主线程也需要锁一次,所以cnt + 1,主线程等待一组10个线程执行完,
		//同时主线程释放锁,达到屏障点,执行下一组线程
		barrier = new CyclicBarrier(cnt + 1);
		//每一次,可运行的任务锁
		MAX_TASK = cnt;
	}

	public void doWork(final Runnable work) {
		new Thread() {
			public void run() {
				work.run();
				try {
					//释放屏障共享锁
					int index = barrier.await();
					//检查进度
					doWithIndex(index);
				} catch (InterruptedException e) {
					return;
				} catch (BrokenBarrierException e) {
					return;
				}
			}
		}.start();
	}
   /**
    * 检查线程组完成进度,根据不通过的进度,可以做一些通知工作
    * @param index
    */
	private void doWithIndex(int index) {
		if (index == MAX_TASK / 2) {
			System.out.println("Left 50%");
		} 
                if (index == 0) {
			System.out.println("run over");
		}
	}

	public void waitForNext() {
		try {
			//主线程释放屏障共享锁,检查进度
			doWithIndex(barrier.await());
		} catch (InterruptedException e) {
			return;
		} catch (BrokenBarrierException e) {
			return;
		}
	}

	public static void main(String[] args) {
		final int count = 10;
		TestCyclicBarrier demo = new TestCyclicBarrier(count);
		for (int i = 0; i < 100; i++) {
			demo.doWork(new Runnable() {
				public void run() {
					// do something
					try {
						Thread.sleep(1000L);
					} catch (Exception e) {
						return;
					}
				}
			});
			if ((i + 1) % count == 0) {
				/*
				 每10个线程一组,或者锁一个屏障点,当每组的10个线程,都完成时, 才执行下一组线程
				 */
				demo.waitForNext();
			}
		}
	}
}


上述例子描述的是一个周期性处理任务的例子,在这个例子中有一对的任务(100个),希望每10个为一组进行处理,当前仅当上一组任务处理完成后才能进行下一组,另外在每一组任务中,当任务剩下50%,所有任务执行完成时向观察者发出通知。
在这个例子中,CyclicBarrierDemo 构建了一个count+1的任务组(其中一个任务时为了外界方便挂起主线程)。每一个子任务里,任务本身执行完毕后都需要等待同组内其它任务执行完成后才能继续。同时在剩下任务50%、30%已经0时执行特殊的其他任务(发通知)。很显然CyclicBarrier有以下几个特点:
•await()方法将挂起线程,直到同组的其它线程执行完毕才能继续
•await()方法返回线程执行完毕的索引,注意,索引时从任务数-1开始的,也就是第一个执行完成的任务索引为parties-1,最后一个为0,这个parties为总任务数,清单中是cnt+1
•CyclicBarrier 是可循环的,显然名称说明了这点。在清单1中,每一组任务执行完毕就能够执行下一组任务。
另外除了CyclicBarrier除了以上特点外,还有以下几个特点:
•如果屏障操作不依赖于挂起的线程,那么任何线程都可以执行屏障操作。在清单1中可以看到并没有指定那个线程执行50%、30%、0%的操作,而是一组线程(cnt+1)个中任何一个线程只要到达了屏障点都可以执行相应的操作
•CyclicBarrier 的构造函数允许携带一个任务,这个任务将在0%屏障点执行,它将在await()==0后执行。
•CyclicBarrier 如果在await时因为中断、失败、超时等原因提前离开了屏障点,那么任务组中的其他任务将立即被中断,以InterruptedException异常离开线程。
•所有await()之前的操作都将在屏障点之前运行,也就是CyclicBarrier 的内存一致性效果
CyclicBarrier 的所有API如下:
•public CyclicBarrier(int parties) 创建一个新的CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动barrier 时执行预定义的操作。
•public CyclicBarrier(int parties, Runnable barrierAction) 创建一个新的CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动barrier 时执行给定的屏障操作,该操作由最后一个进入barrier 的线程执行。
•public int await() throws InterruptedException, BrokenBarrierException 在所有参与者都已经在此barrier 上调用await 方法之前,将一直等待。
•public int await(long timeout,TimeUnit unit) throws InterruptedException, BrokenBarrierException,TimeoutException 在所有参与者都已经在此屏障上调用await 方法之前将一直等待,或者超出了指定的等待时间。
•public int getNumberWaiting() 返回当前在屏障处等待的参与者数目。此方法主要用于调试和断言。
•public int getParties() 返回要求启动此barrier 的参与者数目。
•public boolean isBroken() 查询此屏障是否处于损坏状态。
•public void reset() 将屏障重置为其初始状态。
符:


  • 大小: 33.8 KB
0
0
分享到:
评论

相关推荐

    CountDownLatch和CyclicBarrier用法实例大全

    - 使用CyclicBarrier实现多线程分治策略,每个子任务完成后来一次全局计算的例子。 - 线程间的异常处理,包括中断和超时的处理。 - 结合Future和ExecutorService,进一步提高并发性能和灵活性。 - 在大型项目中的...

    Java并发编程(CyclicBarrier)实例详解

    Java并发编程(CyclicBarrier)实例详解 Java并发编程(CyclicBarrier)实例详解主要介绍了Java并发编程(CyclicBarrier)实例详解的相关资料,JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,...

    Java并发实例之CyclicBarrier的使用

    Java并发实例之CyclicBarrier的使用 CyclicBarrier是Java中的一种多线程并发控制实用工具,和CountDownLatch非常类似,它也可以实现线程间的计数等待,但是它的功能比CountDownLatch更加复杂且强大。CyclicBarrier...

    Java并发编程之栅栏(CyclicBarrier)实例介绍

    2. **CyclicBarrier的使用**: - **构造器**:创建CyclicBarrier时需要指定线程数量n和可选的屏障动作。屏障动作会在所有线程都到达屏障点后执行。 - **await方法**:每个线程在到达屏障点时调用await方法,这会...

    java多线程之CyclicBarrier的使用方法

    Java多线程之CyclicBarrier的使用方法 Java多线程之CyclicBarrier的使用方法是Java多线程编程中的一种同步机制,用于实现多个线程之间的同步协作。CyclicBarrier是Java 5中引入的一种同步机制,用于让多个线程等待...

    CyclicBarrier用法.docx

    1. **重复使用性**:与CountDownLatch不同,CyclicBarrier可以在所有线程都达到屏障点后重置,允许再次使用。这意味着一旦所有线程都完成各自的任务并调用await()方法,屏障将被重置,计数器恢复到初始值,可以进行...

    Java中CyclicBarrier的用法分析

    `CyclicBarrier`的名字来源于它的可重用性,一旦一组线程通过了屏障,它可以重置并再次使用,而不是像`CountDownLatch`那样只能使用一次。 在上述的测试代码中,我们创建了一个`CyclicBarrier`实例,设置了线程数为...

    Java中的CyclicBarrier类最全讲义

    要使用`CyclicBarrier`,首先需要创建一个实例对象。在构造函数中,我们需要指定参与线程的数量以及当所有线程都到达屏障点时所要执行的操作(如果有的话)。这是一个典型的使用示例: ```java import java.util....

    java高级编程100实例

    10. **并发工具**:如CountDownLatch、CyclicBarrier、Semaphore等,这些工具可以帮助构建复杂的并发程序,实例可能展示如何有效使用它们。 11. **Java 8及以后的新特性**:如Lambda表达式、Stream API、Optional类...

    140个Java源码实例

    15. **并发编程**:Java提供了丰富的并发工具类,如CountDownLatch、CyclicBarrier、Semaphore等,实例将展示如何高效地管理并发任务。 通过逐一研究这些源码实例,不仅可以加深对Java语言的理解,还能提升实际编程...

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

    1. **初始化:** 使用给定的计数值创建一个 CountDownLatch 实例。 2. **递减计数器:** 在需要完成的工作完成后,调用 `countDown()` 方法来递减计数器。 3. **等待:** 其他线程调用 `await()` 方法来等待计数器的...

    Java高级编程实例 100个

    10. **并发工具类**:如Semaphore(信号量)、CountDownLatch(倒计时锁)、CyclicBarrier(回环栅栏)等,用于控制并发访问和同步。 通过这100个实例,初学者不仅能掌握Java高级特性,还能提升问题解决能力和实际...

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

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

    java多线程编程实例_Source

    实例中可能涵盖了这两种方式的使用,并通过不同示例解释它们的异同和适用场景。 二、线程控制 1. 同步机制:包括synchronized关键字和Lock接口(如ReentrantLock可重入锁)。synchronized用于解决共享资源的并发...

    Android开发必备实例

    13. **多线程**:了解如何使用线程池、线程同步机制(如synchronized关键字、CountDownLatch、CyclicBarrier)对提高应用性能至关重要。 14. **依赖注入**:如使用Dagger 2或Koin进行依赖注入,可简化代码结构,...

    SUN公司的java实例代码

    15. **并发工具**:如Semaphore、CyclicBarrier、ExecutorService等,这些工具在多线程编程中非常有用,实例可能有它们的应用。 通过研究这些" SUN公司的java实例手册 ",无论是初学者还是经验丰富的开发者,都能...

    JAVA100例之实例64 JAVA线程间通讯

    在"JAVA100例之实例64 JAVA线程间通讯"这个主题中,我们将深入探讨Java中实现线程间通信的几种主要方法。 1. **共享数据**:最直观的线程间通信方式是通过共享内存空间,即共享变量。只要对共享变量的操作是线程...

    JAVA多线程的实例

    当你有一个实现了`Runnable`接口的类时,你可以创建一个`Thread`对象并传入你的`Runnable`实例,如: ```java Runnable task = new MyRunnable(); Thread thread = new Thread(task); thread.start(); ``` 这里,`...

    Java异步调用转同步方法实例详解

    Java中将异步调用转换为同步调用有多种方法,本文将详细介绍五种方法:使用wait和notify方法、使用条件锁、使用Future、使用CountDownLatch、使用CyclicBarrier。 1. 使用wait和notify方法 wait和notify方法是...

    Java程序设计技巧与开发实例

    Java提供了丰富的并发工具,如Semaphore、CountDownLatch和CyclicBarrier,学习者需了解其用法和适用场景。 除此之外,Java集合框架是存储和操作数据的重要工具,包括List、Set、Map等接口及其实现类。学习者应熟悉...

Global site tag (gtag.js) - Google Analytics