寒假打卡13-1月28日
Java 并发工具类——BlockingQueue、Exchanger、Phaser
Java 并发工具类提供了一组强大的工具来简化多线程编程中的任务协调和同步工作。这些工具包括 BlockingQueue
、Exchanger
和 Phaser
,它们分别用于实现线程间的安全通信、数据交换和多阶段任务的执行。在本篇文章中,我们将详细介绍这些工具类的使用方法和应用场景。
BlockingQueue
BlockingQueue
是一个支持阻塞操作的队列接口,它可以在队列为空时阻塞获取操作,在队列满时阻塞插入操作。BlockingQueue
适用于生产者-消费者模式。
常用实现类
ArrayBlockingQueue
:一个基于数组的有界阻塞队列。LinkedBlockingQueue
:一个基于链表的可选有界阻塞队列。PriorityBlockingQueue
:一个支持优先级排序的无界阻塞队列。SynchronousQueue
:一个没有内部容量的阻塞队列,每个插入操作必须等待对应的移除操作。
示例代码
下面是一个使用 ArrayBlockingQueue
的生产者-消费者示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueDemo {
public static void main(String[] args) {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
// 生产者线程
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
queue.put(i);
System.out.println("Produced: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// 消费者线程
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
int item = queue.take();
System.out.println("Consumed: " + item);
Thread.sleep(200);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
在上述代码中,生产者线程不断向队列中插入元素,而消费者线程从队列中取出元素。通过 BlockingQueue
的阻塞机制,生产者和消费者可以安全地进行数据交换。
Exchanger
Exchanger
是一个用于线程间数据交换的同步点。两个线程可以在交换点交换数据,当两个线程都到达交换点时,它们交换各自的数据。
使用场景
- 线程间的数据交换
- 双向数据流的实现
示例代码
下面是一个使用 Exchanger
的示例,展示了两个线程间的数据交换:
import java.util.concurrent.Exchanger;
public class ExchangerDemo {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
// 线程 A
Thread threadA = new Thread(() -> {
try {
String data = "Data from Thread A";
System.out.println("Thread A is exchanging data: " + data);
String receivedData = exchanger.exchange(data);
System.out.println("Thread A received data: " + receivedData);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// 线程 B
Thread threadB = new Thread(() -> {
try {
String data = "Data from Thread B";
System.out.println("Thread B is exchanging data: " + data);
String receivedData = exchanger.exchange(data);
System.out.println("Thread B received data: " + receivedData);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
threadA.start();
threadB.start();
}
}
在上述代码中,线程 A 和线程 B 在交换点交换各自的数据。当两个线程都到达交换点时,它们交换数据,然后继续执行。
Phaser
Phaser
是一个更灵活的同步辅助类,用于在多阶段任务中协调多个线程。与 CountDownLatch
和 CyclicBarrier
不同,Phaser
支持动态调整参与者的数量,并允许线程在多个阶段之间进行同步。
使用场景
- 多阶段任务的执行
- 动态调整参与者数量的并发任务
示例代码
下面是一个使用 Phaser
的示例,展示了一个多阶段任务的执行:
import java.util.concurrent.Phaser;
public class PhaserDemo {
public static void main(String[] args) {
Phaser phaser = new Phaser(1); // 注册主线程
for (int i = 0; i < 3; i++) {
int threadId = i;
phaser.register(); // 注册参与者线程
new Thread(() -> {
for (int phase = 0; phase < 3; phase++) {
System.out.println("Thread " + threadId + " is working on phase " + phase);
phaser.arriveAndAwaitAdvance(); // 到达并等待其他线程
}
phaser.arriveAndDeregister(); // 完成并取消注册
}).start();
}
for (int phase = 0; phase < 3; phase++) {
phaser.arriveAndAwaitAdvance(); // 主线程等待其他线程完成当前阶段
System.out.println("Main thread completed phase " + phase);
}
phaser.arriveAndDeregister(); // 主线程完成并取消注册
}
}
在上述代码中,主线程和三个参与者线程在三个阶段之间进行同步。每个阶段结束后,所有线程都等待其他线程完成当前阶段,然后继续执行下一阶段。
总结
Java 并发工具类提供了一组强大的工具来简化多线程编程中的任务协调和同步工作。BlockingQueue
适用于生产者-消费者模式,Exchanger
用于线程间的数据交换,Phaser
用于多阶段任务的执行。通过合理使用这些工具类,我们可以编写出更加高效和健壮的多线程程序。
希望通过本篇文章,大家对 Java 并发工具类有了更深入的了解。在接下来的文章中,我们将继续探讨更多关于 Java 并发编程的知识点,敬请期待!