Java多线程之CyclicBarrier的使用方法
简介
CyclicBarrier是Java多线程中的一个工具类,它可以用来构建可重用的同步对象,可以让一组线程在到达某个屏障时阻塞,直到所有的线程都到达屏障时,在继续执行。与CountDownLatch类似,都是多线程同步工具,但CyclicBarrier可以通过它的reset()方法,重用一次。
CyclicBarrier的构造方法如下:
public CyclicBarrier(int parties, Runnable barrierAction)
其中parties表示需要同步的线程数,barrierAction是当所有线程到达屏障时要执行的内容。
示例1
问题描述:假设有三个线程a、b、c,分别打印1、2、3,要求三个线程交替打印,现在使用CyclicBarrier来实现。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
static CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println();
}
});
static int count = 1;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
cyclicBarrier.await();
System.out.print(count++);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
cyclicBarrier.await();
System.out.print(count++);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
cyclicBarrier.await();
System.out.print(count++);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
}
以上代码定义了一个CyclicBarrier对象,该对象在初始化时指定了3个参与者和一个Runnable对象,在所有参与者到达屏障时会执行Runnable中的run方法。
三个线程各自启动并执行run方法,调用cyclicBarrier.await()方法来阻塞,直到所有线程都到达屏障,才会执行后续代码。
运行结果如下:
123
456
789
...
示例2
问题描述:定义三个线程,分别打印10个字母,可以多次循环打印,要求每次循环打印完毕后,等待一秒,再开始下一次循环,并使用CyclicBarrier来实现。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo2 {
static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
public static void main(String[] args) {
final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWX".toCharArray();
for (int i = 0; i < 3; i++) {
final int index = i;
new Thread(new Runnable() {
@Override
public void run() {
int count = 0;
while (true) {
try {
if (count == 3) {
System.out.println("Thread " + index + " finished printing " + count + " loops.");
cyclicBarrier.await();
count = 0;
}
Thread.sleep(1000);
for (int j = 0; j < 10; j++) {
System.out.print(chars[j + index * 10]);
}
System.out.println();
count++;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
}
}
以上代码用CyclicBarrier实现了一个循环打印字母的例子。
CyclicBarrier对象在初始化时指定了3个参与者,每个参与者都会执行run方法中的循环打印字母的代码。
当每个参与者打印完3次10个字母后,会调用cyclicBarrier.await()方法进入等待状态,直到所有参与者都完成后,才会让所有参与者同时开始下一轮打印。
控制台输出如下:
ABCDEFGHIJ
KLMNOPQRST
UVWXYZABCD
Thread 0 finished printing 3 loops.
ABCDEFGHIJ
KLMNOPQRST
UVWXYZABCD
Thread 1 finished printing 3 loops.
ABCDEFGHIJ
KLMNOPQRST
UVWXYZABCD
Thread 2 finished printing 3 loops.
...
总结
在使用CyclicBarrier时,需要设置参与者数和可重用的Runnable对象,在屏障处阻塞的线程可以调用await()方法一起等待,当所有线程都到达屏障处时,在执行Runnable对象中的任务。
CyclicBarrier是一个很有用的多线程同步工具,可以用于实现复杂的线程控制逻辑。在使用时,需要注意多线程的安全问题,如同步、死锁等问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程之CyclicBarrier的使用方法 - Python技术站