Java 并发编程中,java.util.concurrent
(简称 JUC)包提供了多种同步器工具,包括 CyclicBarrier
, Exchanger
, 和 Phaser
。这些工具特别设计用于多线程环境,可以提高并发程序的性能和安全性。下面将详细介绍这些同步器工具的特点及其使用方式。
CyclicBarrier
CyclicBarrier
是一种协调工具类,它允许一组线程相互等待,直到到达某个公共屏障点(barrier point)。当所有参与的线程都到达屏障点时,所有线程都被释放,然后可以继续执行。
特点:
- 可以被多次重用。
- 支持在所有线程到达屏障点后执行一个回调函数。
- 适用于需要一组线程同步执行的场景。
示例代码:
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
public class CyclicBarrierExample {
public static void main(String[] args) {
final CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("All threads have reached the barrier. Resetting...");
});
// 创建三个线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " is starting work");
try {
Thread.sleep(1000); // 模拟工作
barrier.await(); // 等待其他线程
} catch (InterruptedException | BrokenBarrierException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + " has passed the barrier");
}).start();
}
}
}
Exchanger
Exchanger
是一种协调工具类,它允许两个线程交换对象。当两个线程都到达交换点时,它们会交换各自持有的对象,并继续执行。
特点:
- 专门用于两个线程之间的数据交换。
- 支持任意类型的对象交换。
- 适用于需要在两个线程之间传递数据的场景。
示例代码:
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
final Exchanger<String> exchanger = new Exchanger<>();
// 创建两个线程
Thread thread1 = new Thread(() -> {
String data1 = "Data from Thread 1";
try {
System.out.println(Thread.currentThread().getName() + " is exchanging data");
data1 = exchanger.exchange(data1);
System.out.println(Thread.currentThread().getName() + " received data: " + data1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread thread2 = new Thread(() -> {
String data2 = "Data from Thread 2";
try {
System.out.println(Thread.currentThread().getName() + " is exchanging data");
data2 = exchanger.exchange(data2);
System.out.println(Thread.currentThread().getName() + " received data: " + data2);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread1.start();
thread2.start();
}
}
Phaser
Phaser
是一种协调工具类,它类似于 CyclicBarrier
,但提供了更灵活的管理参与线程的方式。Phaser
可以动态注册和注销参与线程,并且可以在每个阶段结束时决定是否继续执行下一个阶段。
特点:
- 动态注册和注销参与线程。
- 支持多个阶段,每个阶段可以有不同的参与者。
- 适用于需要动态调整参与线程集合的场景。
示例代码:
import java.util.concurrent.Phaser;
public class PhaserExample {
public static void main(String[] args) {
final Phaser phaser = new Phaser(3) { // 初始参与者数量为3
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("Phase " + phase + " completed by all parties.");
return phase % 2 == 0; // 每隔一个阶段停止
}
};
// 创建三个线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
for (int j = 0; j < 2; j++) {
System.out.println(Thread.currentThread().getName() + " is working in phase " + j);
try {
Thread.sleep(1000); // 模拟工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
phaser.arriveAndAwaitAdvance(); // 等待其他线程
}
phaser.arriveAndDeregister(); // 注销线程
}).start();
}
}
}
总结
CyclicBarrier
, Exchanger
, 和 Phaser
都是 Java 并发编程中常用的同步工具,它们各自解决了不同的问题。
- CyclicBarrier 用于一组线程相互等待,直到到达某个公共屏障点。适用于需要一组线程同步执行的场景。
- Exchanger 用于两个线程之间的数据交换。适用于需要在两个线程之间传递数据的场景。
- Phaser 提供了更灵活的管理参与线程的方式,适用于需要动态调整参与线程集合的场景。
在使用这些同步工具时,通常会结合具体的并发需求来选择合适的工具。这些工具可以有效地帮助管理线程间的同步问题,提高并发性能。