在本文中,我们将介绍Java中的CyclicBarrier。在Java 5中,CyclicBarrier与其他并发实用程序(如CountDownLatch,ConcurrentHashMap和BlockingQueue)一起引入。
CyclicBarrier是同步的辅助工具,它允许线程集在公共的屏障点处彼此等待。之所以称为循环的,是因为一旦释放等待的线程,它便可以重用。
例如:
假设您有3个线程,您希望所有线程(称为当事人)达到一个共同点,然后只有它们才可以继续前进。在这种情况下,您可以将CyclicBarrier与3个当事人一起使用,一旦3个线程达到一个共同点可以调用一个将实现可运行接口的事件,并释放三个线程。
CountDownLatch和CyclicBarrier之间的区别
CyclicBarrier和CoundDownLatch之间的主要区别是CyclicBarrier可以重用。一次使用后不能使用CountDownLatch。您可以阅读CountDownLatch和CyclicBarrier之间的更多区别。
Java CyclicBarrier示例:
步骤1:在包.src.org.arpit.java2blog中创建一个名为“ RunnableTask.java”的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package org.arpit.java2blog;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class RunnableTask implements Runnable{
CyclicBarrier cyclicBarrier;
long sleepTime;
RunnableTask(CyclicBarrier cyclicBarrier,long sleepTime){
this.cyclicBarrier=cyclicBarrier;
this.sleepTime=sleepTime;
}
@Override
public void run() {
try {
Thread.sleep(sleepTime);
System.out.println(Thread.currentThread().getName() +
" is waiting for "+(cyclicBarrier.getParties()-cyclicBarrier.getNumberWaiting()-1)+
" other threads to reach common barrier point");
/*
* when 3 parties will call await() method (i.e. common barrier point)
* CyclicBarrrierEvent will be triggered and all waiting threads will be released.
*/
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("As "+cyclicBarrier.getParties()+ " threads have reached common barrier point "
+ Thread.currentThread().getName() +
" has been released");
}
}
|
这是一个Runnable任务,将由每个线程执行。
步骤2:在包.src.org.arpit.java2blog中创建一个名为“ CyclicBarrierFinishEvent.java”的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package org.arpit.java2blog;
public class CyclicBarrierFinishEvent implements Runnable{
public void run() {
System.out.println("As 3 threads have reached common barrier point "
+ ", CyclicBarrrierFinishEvent has been triggered");
System.out.println("You can update shared variables if any");
}
}
|
当3个参与方(由CyclicBarrier对象初始化)到达一个公共障碍点时,将调用CyclicBarrierFinishEvent。
步骤3:在包.src.org.arpit.java2blog中创建一个名为“ CyclicBarrierMain.java”的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package org.arpit.java2blog;
import java.util.concurrent.CyclicBarrier;
/** @author Arpit Mandliya*/
public class CyclicBarrierMain {
public static void main(String[] args) {
/*
* Create CountDownLatch with 3 parties, when all 3 parties
* will reach common barrier point CyclicBarrrierFinishEvent will be
* triggered
*/
CyclicBarrier cyclicBarrier=new CyclicBarrier(3 ,new CyclicBarrierFinishEvent());
RunnableTask runnableTask1=new RunnableTask(cyclicBarrier,1000);
RunnableTask runnableTask2=new RunnableTask(cyclicBarrier,2000);
RunnableTask runnableTask3=new RunnableTask(cyclicBarrier,3000);
//Create and start 3 threads
new Thread(runnableTask1,"Thread-1").start();
new Thread(runnableTask2,"Thread-2").start();
new Thread(runnableTask3,"Thread-3").start();
/*
* We are reusing cyclic barrier using below threads
* */
RunnableTask runnableTask4=new RunnableTask(cyclicBarrier,4000);
RunnableTask runnableTask5=new RunnableTask(cyclicBarrier,5000);
RunnableTask runnableTask6=new RunnableTask(cyclicBarrier,6000);
// Create and start 3 more threads
new Thread(runnableTask4,"Thread-4").start();
new Thread(runnableTask5,"Thread-5").start();
new Thread(runnableTask6,"Thread-6").start();
}
}
|
让我们运行程序,然后我们将理解输出:
线程2等待其他1个线程到达公共障碍点
线程3等待其他0个线程到达公共障碍点
由于3个线程到达了公共障碍点,已触发CyclicBarrrierFinishEvent。
如果有以下任何情况,您可以更新共享变量:
3个线程已到达公共障碍点Thread-3已释放
3个线程已到达公共障碍点Thread-1已释放
3个线程已到达公共障碍点Thread- 2已发布
线程4正在等待其他2个线程到达公共障碍点
线程5正在等待其他2个线程到达公共障碍点
线程6正在等待其他0个线程到达公共障碍点
由于3个线程已到达公共障碍点,CyclicBarrrierFinishEvent已触发
您可以更新共享变量(如果有)
当3个线程已到达公共障碍点时线程6已被释放
3线程已达到公共障碍点Thread-4已被释放
由于3个线程已达到公共障碍点Thread-5已被释放
下图将使您更好地理解输出。
这就是关于Java CyclicBarrier示例的全部内容。