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 = "https://www.cnblogs.com/yaoqian/p/Data from producer";
System.out.println("Producer is sending: " + data);
String receivedData = https://www.cnblogs.com/yaoqian/p/exchanger.exchange(data);
System.out.println("Producer received: " + receivedData);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String data = "https://www.cnblogs.com/yaoqian/p/Data from consumer";
System.out.println("Consumer is sending: " + data);
String receivedData = https://www.cnblogs.com/yaoqian/p/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

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/553964.html
標籤:其他
上一篇:4.4. 物件序列化與反序列化
下一篇:返回列表
