下面开始为大家详细讲解Java多线程CyclicBarrier的使用案例。
什么是CyclicBarrier?
CyclicBarrier是Java多线程中的一个构造器,它可以协调多线程间的运行,实现多个线程阻塞至某个状态之后再全部同时执行。可以说CyclicBarrier是控制多线程执行时序的一种工具。
CyclicBarrier的使用场景
CyclicBarrier的使用场景一般是多个线程需要同步执行,当所有线程都到达某个状态时再同时执行。比如,我们需要计算一个复杂的数学问题,可以让多个线程分别计算一部分,最后将结果汇总。但在汇总之前,我们需要先等待所有的线程都计算完成。这时,CyclicBarrier就能够派上用场。
CyclicBarrier的几个重要方法
CyclicBarrier有几个重要方法,这里做一下简要介绍:
CyclicBarrier(int parties)
构造方法,表示一共有parties个线程需要协调同步。
void await()
当前线程调用此方法表示到达栅栏,等待其他线程到达。如果所有需要等待的线程都已到达,则开始执行等待线程的操作,否则会阻塞等待。
void reset()
重置屏障,恢复到初始状态。所有等待的线程都会抛出BrokenBarrierException异常。
CyclicBarrier使用例子1
下面我们通过一个简单的例子来演示CyclicBarrier的使用方式。
场景描述:
现在有三个线程需要协调同步,它们分别从某个起点出发,经过不同的路线,最终到达一个终点。在路途中,它们需要等待其他线程,然后再一起前行。
示例代码如下:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
int n = 3;
CyclicBarrier cyclicBarrier = new CyclicBarrier(n, new Runnable() {
// 所有线程到达屏障时,会先执行这个线程
@Override
public void run() {
System.out.println("All threads arrived at the barrier.");
}
});
for (int i = 0; i < n; i++) {
new Thread(new Task(i, cyclicBarrier)).start();
}
}
}
class Task implements Runnable {
private int id;
private CyclicBarrier cyclicBarrier;
public Task(int id, CyclicBarrier cyclicBarrier) {
this.id = id;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
System.out.println("Thread " + id + " arrived. Waiting for others.");
cyclicBarrier.await();
System.out.println("Thread " + id + " continue.");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
输出结果如下:
Thread 0 arrived. Waiting for others.
Thread 1 arrived. Waiting for others.
Thread 2 arrived. Waiting for others.
All threads arrived at the barrier.
Thread 1 continue.
Thread 0 continue.
Thread 2 continue.
从结果可以看出,三个线程在到达栅栏之后,都等待其他线程,当所有线程都到达之后,就会输出“All threads arrived at the barrier.”,然后三个线程再一起继续执行。
在这个例子中,我们设置了一个Runnable对象,在所有线程到达屏障时执行。Runnable对象应该只占用极少的时间,否则会影响其他线程的运行。这里只是一个示例,在实际使用时,根据实际情况选择是否需要设置Runnable对象。
CyclicBarrier使用例子2
下面再举一个稍微复杂一点的例子,来展示CyclicBarrier的具体用法。
场景描述:
现在有四个人要一起参加比赛,比赛有两个环节,分别为跑步和游泳。每个人都要在规定的时间内完成这两个环节,然后等待其他人完成。当所有人都完成时,比赛结束,输出所有人的完成时间。
示例代码如下:
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
int n = 4;
CyclicBarrier cyclicBarrier = new CyclicBarrier(n, new Runnable() {
@Override
public void run() {
System.out.println("All players finished the game.");
}
});
for (int i = 0; i < n; i++) {
new Thread(new Player(i, cyclicBarrier)).start();
}
}
}
class Player implements Runnable {
private int id;
private CyclicBarrier cyclicBarrier;
public Player(int id, CyclicBarrier cyclicBarrier) {
this.id = id;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
System.out.println("Player " + id + " started running.");
Thread.sleep(new Random().nextInt(3000));
System.out.println("Player " + id + " finished running.");
cyclicBarrier.await(); // 等待其他选手完成跑步
System.out.println("Player " + id + " started swimming.");
Thread.sleep(new Random().nextInt(3000));
System.out.println("Player " + id + " finished swimming.");
cyclicBarrier.await(); // 等待其他选手完成游泳
System.out.println("Player " + id + " finished the game.");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
输出结果如下:
Player 0 started running.
Player 3 started running.
Player 1 started running.
Player 2 started running.
Player 3 finished running.
Player 0 finished running.
All players finished running.
Player 2 finished running.
Player 1 finished running.
All players finished swimming.
Player 3 finished the game.
Player 0 finished the game.
Player 1 finished the game.
Player 2 finished the game.
All players finished the game.
从结果可以看出,四个选手首先按顺序开始跑步,每个选手需要在规定的时间内完成跑步,然后等待其他选手。当所有选手都完成跑步时,就会输出“All players finished running.”,然后四个选手再按顺序开始游泳。完成游泳后,再次等待其他选手,当所有选手都完成比赛时,输出所有选手的完成时间。
在这个例子中,我们使用CyclicBarrier来协调选手的跑步和游泳两个环节,使得所有选手能够在同一时刻完成两个环节。同时,我们也有机会在所有选手都完成比赛后观察运行结果,以便更好地了解CyclicBarrier的运行机制。
以上就是关于Java多线程CyclicBarrier的使用案例,希望对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程CyclicBarrier的使用案例,让线程起步走 - Python技术站