5.5.1 CountDownLatch
CountDownLatch
是一个同步辅助类,它容许一个或多个线程期待,直到其余线程实现一组操作。CountDownLatch
有一个计数器,当计数器减为0时,期待的线程将被唤醒。计数器只能缩小,不能减少。
示例:应用CountDownLatch期待所有线程实现工作
假如咱们有一个工作须要三个子工作实现,咱们能够应用CountDownLatch
来期待所有子工作实现。
import java.util.concurrent.CountDownLatch;public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3); for (int i = 1; i <= 3; i++) { final int taskNumber = i; new Thread(() -> { System.out.println("Task " + taskNumber + " started"); try { Thread.sleep(1000 * taskNumber); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Task " + taskNumber + " completed"); latch.countDown(); }).start(); } System.out.println("Waiting for all tasks to complete..."); latch.await(); System.out.println("All tasks completed"); }}
在这个示例中,咱们创立了一个CountDownLatch
并设置初始计数器为3。每个子工作实现后,调用latch.countDown()
缩小计数器。主线程调用latch.await()
期待所有子工作实现。
5.5.2 CyclicBarrier
CyclicBarrier
是一个同步辅助类,它容许一组线程互相期待,直到所有线程都筹备好继续执行。当所有线程都达到屏障点时,屏障将关上。CyclicBarrier
能够重复使用。
示例:应用CyclicBarrier同步多个线程
假如咱们有三个线程须要在某个点同步,咱们能够应用CyclicBarrier
实现这个目标。
import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All threads are ready to proceed")); for (int i = 1; i <= 3; i++) { final int taskNumber = i; new Thread(() -> { System.out.println("Task " + taskNumber + " is ready"); try { barrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println("Task " + taskNumber + " is proceeding"); }).start(); } }}
在这个示例中,咱们创立了一个CyclicBarrier
并设置参与者数量为3。每个线程在筹备好继续执行之前调用barrier.await()
。当所有线程都筹备好时,屏障将关上,所有线程将继续执行。
5.5.3 Semaphore
Semaphore
是一个计数信号量,它保护了一个许可集。线程能够申请许可,如果有可用的许可,线程将取得许可并继续执行。否则,线程将阻塞,直到有可用的许可。许可能够由任何线程开释。Semaphore
可用于实现资源池、限度并发拜访等。
示例:应用Semaphore限度并发拜访
假如咱们有一个只能同时解决三个申请的服务器,咱们能够应用Semaphore
来实现并发拜访限度。
import java.util.concurrent.Semaphore;public class SemaphoreExample { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 10; i++) final int clientNumber = i; new Thread(() -> { try { System.out.println("Client " + clientNumber + " is trying to connect"); semaphore.acquire(); System.out.println("Client " + clientNumber + " is connected"); Thread.sleep(2000); System.out.println("Client " + clientNumber + " is disconnected"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }).start(); } }}
在这个示例中,咱们创立了一个Semaphore
并设置初始许可数量为3。每个客户端线程在连贯服务器之前调用semaphore.acquire()
申请许可。当许可可用时,线程将取得许可并继续执行。线程实现后,调用semaphore.release()
开释许可。
5.5.4 Exchanger
Exchanger
是一个同步辅助类,它容许两个线程在一个临界点替换数据。当两个线程都达到替换点时,它们将替换数据。Exchanger
能够用于遗传算法、管道设计等。
示例:应用Exchanger替换数据
假如咱们有两个线程,一个生成数据,另一个解决数据。咱们能够应用Exchanger
在这两个线程之间替换数据。
import java.util.concurrent.Exchanger;public class ExchangerExample { public static void main(String[] args) { Exchanger<String> exchanger = new Exchanger<>(); new Thread(() -> { try { String data = "Data from producer"; System.out.println("Producer is sending: " + data); String receivedData = exchanger.exchange(data); System.out.println("Producer received: " + receivedData); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { String data = "Data from consumer"; System.out.println("Consumer is sending: " + data); String receivedData = exchanger.exchange(data); System.out.println("Consumer received: " + receivedData); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); }}
在这个示例中,咱们创立了一个Exchanger
。生产者和消费者线程在替换数据前调用exchanger.exchange(data)
。当两个线程都达到替换点时,它们将替换数据。
5.5.5 Phaser
Phaser
是一个灵便的同步辅助类,它容许一组线程互相期待,直到所有线程都筹备好继续执行。与CyclicBarrier
相似,但Phaser
更加灵便,能够动静调整参与者数量和反对多个阶段。
示例:应用Phaser同步多个线程
假如咱们有三个线程须要在某个点同步,咱们能够应用Phaser
实现这个目标。
import java.util.concurrent.Phaser;public class PhaserExample { public static void main(String[] args) { Phaser phaser = new Phaser(3); for (int i = 1; i <= 3; i++) { final int taskNumber = i; new Thread(() -> { System.out.println("Task " + taskNumber + " is ready"); phaser.arriveAndAwaitAdvance(); System.out.println("Task " + taskNumber + " is proceeding"); }).start(); } }}
在这个示例中,咱们创立了一个Phaser
并设置参与者数量为3。每个线程在筹备好继续执行之前调用phaser.arriveAndAwaitAdvance()
。当所有线程都筹备好时,屏障将关上,所有线程将继续执行。
这些并发工具类为Java多线程编程提供了弱小的反对,帮忙咱们更轻松地实现各种同步和并发场景。心愿这些示例能帮忙你了解并把握这些工具类的用法。
举荐浏览:
https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA
https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g