嘉興做網(wǎng)站費(fèi)用重慶百度推廣電話
一、ReentrantLock
特點(diǎn):獨(dú)占、可重入、公平/非公平、可中斷、支持多個(gè)條件變量
1、常用api
ReentrantLock實(shí)現(xiàn)了Lock接口,Lock類規(guī)范定義了如下方法
- lock():獲取鎖,調(diào)用該方法的線程會(huì)獲取鎖,當(dāng)鎖獲得后,該方法返回
- lockInterruptibly():可中斷得獲取鎖,和lock()方法不同之處在于該方法會(huì)響應(yīng)中斷,即在鎖的獲取中可以中斷當(dāng)前線程
- tryLock():嘗試非阻塞的獲取鎖,調(diào)用該方法后立即返回。如果能夠獲取到返回true,否則返回false
- tryLock(long, TimeUnit):超時(shí)獲取鎖,當(dāng)前線程在三種情況下會(huì)被返回(1、當(dāng)前線程在超時(shí)時(shí)間內(nèi)獲取了鎖 2、當(dāng)前線程在超時(shí)時(shí)間內(nèi)被中斷 3、超時(shí)時(shí)間結(jié)束,返回false)
- unLock():釋放鎖
- newCondition():獲取等待通知組件,該組件和當(dāng)前的鎖綁定,當(dāng)前線程只有獲取了鎖,才能調(diào)用該組件的await()方法,而調(diào)用后,當(dāng)前線程將釋放鎖
2、使用
使用范式:
?如果把lock.lock()加鎖操作放在try里面,可能try里面其它代碼導(dǎo)致加鎖失敗,最后lock.unlock()解鎖操作時(shí)由于沒加鎖成功拋出IllegalMonitorStateException異常
public class ReentrantLockTest {private final ReentrantLock lock = new ReentrantLock();// 庫(kù)存數(shù)量private static int inventoryQuantity = 5;// 減庫(kù)存方法private void reduceInventory() {lock.lock();try {if (inventoryQuantity > 0) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"購(gòu)買了商品,剩余庫(kù)存數(shù):"+--inventoryQuantity);} else {System.out.println(Thread.currentThread().getName()+":已經(jīng)沒有庫(kù)存了");}} finally {lock.unlock();}}public static void main(String[] args) throws InterruptedException {ReentrantLockTest lockTest = new ReentrantLockTest();for (int i = 1; i <= 10; i++) {new Thread(() -> {lockTest.reduceInventory();}).start();}}
}
打印結(jié)果:
Thread-0購(gòu)買了商品,剩余庫(kù)存數(shù):4
Thread-1購(gòu)買了商品,剩余庫(kù)存數(shù):3
Thread-2購(gòu)買了商品,剩余庫(kù)存數(shù):2
Thread-3購(gòu)買了商品,剩余庫(kù)存數(shù):1
Thread-5購(gòu)買了商品,剩余庫(kù)存數(shù):0
Thread-4:已經(jīng)沒有庫(kù)存了
Thread-6:已經(jīng)沒有庫(kù)存了
Thread-9:已經(jīng)沒有庫(kù)存了
Thread-7:已經(jīng)沒有庫(kù)存了
Thread-8:已經(jīng)沒有庫(kù)存了
3、公平鎖和非公平鎖
ReentrantLock支持公平鎖和非公平鎖,默認(rèn)是非公平鎖
- 公平鎖:線程在獲取鎖時(shí),按照等待的先后順序獲取鎖
- 非公平鎖:線程在獲取鎖時(shí),不按照等待的先后順序獲取鎖,而是隨機(jī)獲取鎖
ReentrantLock lock = new ReentrantLock(); //參數(shù)默認(rèn)false,非公平鎖
ReentrantLock lock = new ReentrantLock(true); //公平鎖
非公平鎖在加鎖允許先進(jìn)行CAS操作判斷一次,公平鎖則直接進(jìn)入acquire()方法
4、可重入鎖
可重入鎖又名遞歸鎖,是指在同一個(gè)線程在外層方法獲取鎖的時(shí)候,再進(jìn)入該線程的內(nèi)層方法會(huì)自動(dòng)獲取鎖(前提鎖對(duì)象得是同一個(gè)),不會(huì)因?yàn)橹耙呀?jīng)獲取過(guò)還沒釋放而阻塞。ReentrantLock和synchronized都是可重入鎖,可重入鎖可一定層度避免死鎖。在實(shí)際開發(fā)中,可重入鎖常常 應(yīng)用于遞歸操作、調(diào)用同一個(gè)類中的其他方法、鎖嵌套等場(chǎng)景中
public class ReentrantLockRecursiveTest {private final ReentrantLock lock = new ReentrantLock();/*** 遞歸調(diào)用5次* @param num*/public void recursiveCall(int num) {lock.lock();try {if (num > 5) {return;}System.out.println("執(zhí)行遞歸調(diào)用第"+num+"次");recursiveCall(++num);} finally {lock.unlock();}}public static void main(String[] args) {ReentrantLockRecursiveTest lockRecursiveTest = new ReentrantLockRecursiveTest();lockRecursiveTest.recursiveCall(1);}
}
打印結(jié)果:
執(zhí)行遞歸調(diào)用第1次
執(zhí)行遞歸調(diào)用第2次
執(zhí)行遞歸調(diào)用第3次
執(zhí)行遞歸調(diào)用第4次
執(zhí)行遞歸調(diào)用第5次
5、基于Condition的等待喚醒機(jī)制
java.util.concurrent類庫(kù)中提供Condition類實(shí)現(xiàn)線程之間的協(xié)調(diào)。調(diào)用Condition.await()方法使線程等待,其它線程調(diào)用Condition.signal()或Condition.signalAll()方法喚醒等待的線程
注意:調(diào)用Condition的await()和signal()方法,都必須在lock保護(hù)之內(nèi)
案例:基于ReentrantLock和Condition實(shí)現(xiàn)一個(gè)簡(jiǎn)單隊(duì)列
public class ReentrantLockConditionTest {public static void main(String[] args) {Queue queue = new Queue(5);// 創(chuàng)建生產(chǎn)者線程new Thread(new Producer(queue)).start();// 創(chuàng)建消費(fèi)者線程new Thread(new Customer(queue)).start();}}class Queue {private Object[] items;int size = 0;int takeIndex;int putIndex;private ReentrantLock lock;public Condition notEmpty;public Condition notFull;public Queue(int capacity) {this.items = new Object[capacity];lock = new ReentrantLock();notEmpty = lock.newCondition();notFull = lock.newCondition();}/*** 生產(chǎn)者方法* @param value* @throws InterruptedException*/public void put(Object value) throws InterruptedException {lock.lock();try {while (size == items.length) {// 隊(duì)列滿了 進(jìn)入等待notFull.await();}items[putIndex] = value;if (++putIndex == items.length) {putIndex = 0;}size++;notEmpty.signal();// 隊(duì)列中只要添加一個(gè)對(duì)象就喚醒消費(fèi)者線程} finally {System.out.println("producer生產(chǎn):"+value);lock.unlock();}}/*** 消費(fèi)者方法* @return* @throws InterruptedException*/public Object take() throws InterruptedException {lock.lock();try {// 隊(duì)列空了就讓消費(fèi)者等待while (size == 0) {notEmpty.await();}Object value = items[takeIndex];items[takeIndex] = null;if (++takeIndex == items.length) {takeIndex = 0;}size--;notFull.signal();// 隊(duì)列中只要消費(fèi)一個(gè)對(duì)象就喚醒生產(chǎn)者線程return value;} finally {lock.unlock();}}
}class Producer implements Runnable {private Queue queue;public Producer(Queue queue) {this.queue = queue;}@Overridepublic void run() {try {while (true) {Thread.sleep(1000);queue.put(new Random().nextInt(1000));}} catch (InterruptedException e) {e.printStackTrace();}}
}class Customer implements Runnable {private Queue queue;public Customer (Queue queue) {this.queue = queue;}@Overridepublic void run() {try {while (true) {Thread.sleep(2000);System.out.println("consumer消費(fèi):" + queue.take());}} catch (InterruptedException e) {e.printStackTrace();}}}
6、應(yīng)用場(chǎng)景總結(jié)
ReentrantLock具體應(yīng)用場(chǎng)景如下:
- 解決多線程競(jìng)爭(zhēng)資源的問(wèn)題,例如多個(gè)線程同時(shí)對(duì)同一個(gè)數(shù)據(jù)庫(kù)進(jìn)行寫操作,可以使用ReentrantLock保證每次只有一個(gè)線程能夠?qū)懭搿?/li>
- 實(shí)現(xiàn)多線程任務(wù)的順序執(zhí)行,例如在一個(gè)線程執(zhí)行完某個(gè)任務(wù)后,再讓另一個(gè)線程執(zhí)行任務(wù)。
- 實(shí)現(xiàn)多線程等待/通知機(jī)制,例如在某個(gè)線程執(zhí)行完某個(gè)任務(wù)后,通知其他線程繼續(xù)執(zhí)行任務(wù)。
二、Semaphore
Semaphore(信號(hào)量)是一種用于多線程編程的同步工具,用于控制同時(shí)訪問(wèn)某個(gè)資源的線程數(shù)量。
Semaphore維護(hù)了一個(gè)計(jì)數(shù)器,線程可以通過(guò)調(diào)用acquire()方法來(lái)獲取Semaphore中的許可證,當(dāng)計(jì)數(shù)器為0時(shí),調(diào)用acquire()的線程將被阻塞,直到有其他線程釋放許可證;線程可以通過(guò)調(diào)用release()方法來(lái)釋放Semaphore中的許可證,這會(huì)使Semaphore中的計(jì)數(shù)器增加,從而允許更多的線程訪問(wèn)共享資源。
1、常用api
- permits 表示許可證的數(shù)量(資源數(shù))
- fair 表示公平性,如果這個(gè)設(shè)為 true 的話,下次執(zhí)行的線程會(huì)是等待最久的線程
- acquire() 表示阻塞并獲取許可
- tryAcquire() 方法在沒有許可的情況下會(huì)立即返回 false,要獲取許可的線程不會(huì)阻塞
- release() 表示釋放許可
2、使用
public class SemaphoreTest {// 定義兩個(gè)資源數(shù)private static Semaphore semaphore = new Semaphore(2);private static Executor executor = Executors.newFixedThreadPool(10);public static void main(String[] args) {for (int i = 0; i < 10; i++) {executor.execute(() -> fluidControl());}}public static void fluidControl2() {try {// acquire()會(huì)構(gòu)建同步等待隊(duì)列semaphore.acquire();System.out.println("請(qǐng)求服務(wù)成功");Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}public static void fluidControl() {// tryAcquire()直接CAS返回if (!semaphore.tryAcquire()) {System.out.println("請(qǐng)求被流控了");return;}try {System.out.println("請(qǐng)求服務(wù)成功");Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}
}
3、應(yīng)用場(chǎng)景
以下是一些使用Semaphore的常見場(chǎng)景:
- 限流:Semaphore可以用于限制對(duì)共享資源的并發(fā)訪問(wèn)數(shù)量,以控制系統(tǒng)的流量。
- 資源池:Semaphore可以用于實(shí)現(xiàn)資源池,以維護(hù)一組有限的共享資源。
三、CountDownLatch
CountDownLatch(閉鎖)是一個(gè)同步協(xié)助類,允許一個(gè)或多個(gè)線程等待,直到其他線程完成操作集。
CountDownLatch使用給定的計(jì)數(shù)值(count)初始化。await方法會(huì)阻塞直到當(dāng)前的計(jì)數(shù)值(count),由于countDown方法的調(diào)用達(dá)到0,count為0之后所有等待的線程都會(huì)被釋放,并且隨后對(duì)await方法的調(diào)用都會(huì)立即返回。這是一個(gè)一次性現(xiàn)象 —— count不會(huì)被重置。
1、常用api
- CountDownLatch(int):構(gòu)造方法初始化count數(shù)
- await():等待count減到0后繼續(xù)往后執(zhí)行
- await():等待指定時(shí)長(zhǎng),count值還沒減到0,不再等待繼續(xù)執(zhí)行
- countDown():每調(diào)用一次count就會(huì)減1,減到0為止?
2、使用
public class CountDownLatchTest {private static int[] values = {30, 20, 65, 23, 45};private static int result = 0;private static CountDownLatch coming = new CountDownLatch(values.length);public static void main(String[] args) throws InterruptedException {for (int i = 0; i < values.length; i++) {int tempI = i;new Thread(() -> {result += values[tempI];System.out.println(Thread.currentThread().getName()+"線程計(jì)算的結(jié)果集是:"+result);coming.countDown();}, "Thread_"+i).start();}coming.await();System.out.println("匯總結(jié)果集是:"+result);}
}
3、應(yīng)用場(chǎng)景
以下是使用CountDownLatch的常見場(chǎng)景:
- 并行任務(wù)同步:CountDownLatch可以用于協(xié)調(diào)多個(gè)并行任務(wù)的完成情況,確保所有任務(wù)都完成后再繼續(xù)執(zhí)行下一步操作。
- 多任務(wù)匯總:CountDownLatch可以用于統(tǒng)計(jì)多個(gè)線程的完成情況,以確定所有線程都已完成工作。
- 資源初始化:CountDownLatch可以用于等待資源的初始化完成,以便在資源初始化完成后開始使用。
四、CyclicBarrier
CyclicBarrier(回環(huán)柵欄或循環(huán)屏障),是 Java 并發(fā)庫(kù)中的一個(gè)同步工具,通過(guò)它可以實(shí)現(xiàn)讓一組線程等待至某個(gè)狀態(tài)(屏障點(diǎn))之后再全部同時(shí)執(zhí)行。叫做回環(huán)是因?yàn)楫?dāng)所有等待線程都被釋放以后,CyclicBarrier可以被重用。
1、常用api
// parties表示屏障攔截的線程數(shù)量,每個(gè)線程調(diào)用 await 方法告訴 CyclicBarrier 我已經(jīng)到達(dá)了屏障,然后當(dāng)前線程被阻塞。public CyclicBarrier(int parties)// 用于在線程到達(dá)屏障時(shí),優(yōu)先執(zhí)行 barrierAction,方便處理更復(fù)雜的業(yè)務(wù)場(chǎng)景(該線程的執(zhí)行時(shí)機(jī)是在到達(dá)屏障之后再執(zhí)行)public CyclicBarrier(int parties, Runnable barrierAction)
//指定數(shù)量的線程全部調(diào)用await()方法時(shí),這些線程不再阻塞
// BrokenBarrierException 表示柵欄已經(jīng)被破壞,破壞的原因可能是其中一個(gè)線程 await() 時(shí)被中斷或者超時(shí)
public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException//循環(huán) 通過(guò)reset()方法可以進(jìn)行重置
public void reset()
2、使用
public class CyclicBarrierTest {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(5);CyclicBarrier cyclicBarrier = new CyclicBarrier(5,() -> System.out.println("人齊了,準(zhǔn)備發(fā)車"));for (int i = 0; i < 10; i++) {final int id = i+1;executorService.submit(new Runnable() {@Overridepublic void run() {try {System.out.println(id+"號(hào)馬上就到");int sleepMills = ThreadLocalRandom.current().nextInt(2000);Thread.sleep(sleepMills);System.out.println(id + "號(hào)到了,上車");cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();}catch(BrokenBarrierException e){e.printStackTrace();}}});}}
}
3、應(yīng)用場(chǎng)景
以下是一些常見的 CyclicBarrier 應(yīng)用場(chǎng)景:
- 多線程任務(wù):CyclicBarrier 可以用于將復(fù)雜的任務(wù)分配給多個(gè)線程執(zhí)行,并在所有線程完成工作后觸發(fā)后續(xù)操作。
- 數(shù)據(jù)處理:CyclicBarrier 可以用于協(xié)調(diào)多個(gè)線程間的數(shù)據(jù)處理,在所有線程處理完數(shù)據(jù)后觸發(fā)后續(xù)操作。
4、CyclicBarrier 與 CountDownLatch 區(qū)別
- CountDownLatch 是一次性的,CyclicBarrier 是可循環(huán)利用的
- CountDownLatch 參與的線程的職責(zé)是不一樣的,有的在倒計(jì)時(shí),有的在等待倒計(jì)時(shí)結(jié)束。CyclicBarrier 參與的線程職責(zé)是一樣的。
五、Exchanger
Exchanger是一個(gè)用于線程間協(xié)作的工具類,用于兩個(gè)線程間交換數(shù)據(jù)。具體交換數(shù)據(jù)是通過(guò)exchange方法來(lái)實(shí)現(xiàn)的,如果一個(gè)線程先執(zhí)行exchange方法,那么它會(huì)同步等待另一個(gè)線程也執(zhí)行exchange方法,這個(gè)時(shí)候兩個(gè)線程就都達(dá)到了同步點(diǎn),兩個(gè)線程就可以交換數(shù)據(jù)。
1、常用api
public V exchange(V x) throws InterruptedException
public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
- V exchange(V v):等待另一個(gè)線程到達(dá)此交換點(diǎn)(除非當(dāng)前線程被中斷),然后將給定的對(duì)象傳送給該線程,并接收該線程的對(duì)象。
- V exchange(V v, long timeout, TimeUnit unit):等待另一個(gè)線程到達(dá)此交換點(diǎn),或者當(dāng)前線程被中斷——拋出中斷異常;又或者是等候超時(shí)——拋出超時(shí)異常,然后將給定的對(duì)象傳送給該線程,并接收該線程的對(duì)象。
2、使用
public class ExchangerTest {private static Exchanger exchanger = new Exchanger();static String goods = "電腦";static String money = "$4000";public static void main(String[] args) throws InterruptedException {System.out.println("準(zhǔn)備交易,一手交錢一手交貨...");// 賣家new Thread(new Runnable() {@Overridepublic void run() {System.out.println("賣家到了,已經(jīng)準(zhǔn)備好貨:" + goods);try {String money = (String) exchanger.exchange(goods);System.out.println("賣家收到錢:" + money);} catch (Exception e) {e.printStackTrace();}}}).start();Thread.sleep(3000);// 買家new Thread(new Runnable() {@Overridepublic void run() {try {System.out.println("買家到了,已經(jīng)準(zhǔn)備好錢:" + money);String goods = (String) exchanger.exchange(money);System.out.println("買家收到貨:" + goods);} catch (Exception e) {e.printStackTrace();}}}).start();}
}
3、應(yīng)用場(chǎng)景
Exchanger 可以用于各種應(yīng)用場(chǎng)景,具體取決于具體的 Exchanger 實(shí)現(xiàn)。常見的場(chǎng)景包括:
- 數(shù)據(jù)交換:在多線程環(huán)境中,兩個(gè)線程可以通過(guò) Exchanger 進(jìn)行數(shù)據(jù)交換。
- 數(shù)據(jù)采集:在數(shù)據(jù)采集系統(tǒng)中,可以使用 Exchanger 在采集線程和處理線程間進(jìn)行數(shù)據(jù)交換。
六、Phaser
Phaser(階段協(xié)同器)是一個(gè)Java實(shí)現(xiàn)的并發(fā)工具類,用于協(xié)調(diào)多個(gè)線程的執(zhí)行。它提供了一些方便的方法來(lái)管理多個(gè)階段的執(zhí)行,可以讓程序員靈活地控制線程的執(zhí)行順序和階段性的執(zhí)行。Phaser可以被視為CyclicBarrier和CountDownLatch的進(jìn)化版,它能夠自適應(yīng)地調(diào)整并發(fā)線程數(shù),可以動(dòng)態(tài)地增加或減少參與線程的數(shù)量。所以Phaser特別適合使用在重復(fù)執(zhí)行或者重用的情況。
1、常用api
構(gòu)造方法
- Phaser(): 參與任務(wù)數(shù)0
- Phaser(int parties) :指定初始參與任務(wù)數(shù)
- Phaser(Phaser parent) :指定parent階段器, 子對(duì)象作為一個(gè)整體加入parent對(duì)象, 當(dāng)子對(duì)象中沒有參與者時(shí),會(huì)自動(dòng)從parent對(duì)象解除注冊(cè)
- Phaser(Phaser parent,int parties) : 集合上面兩個(gè)方法
增減參與任務(wù)數(shù)方法
- int register() 增加一個(gè)任務(wù)數(shù),返回當(dāng)前階段號(hào)。
- int bulkRegister(int parties) 增加指定任務(wù)個(gè)數(shù),返回當(dāng)前階段號(hào)。
- int arriveAndDeregister() 減少一個(gè)任務(wù)數(shù),返回當(dāng)前階段號(hào)。
到達(dá)、等待方法
- int arrive() 到達(dá)(任務(wù)完成),返回當(dāng)前階段號(hào)。
- int arriveAndAwaitAdvance() 到達(dá)后等待其他任務(wù)到達(dá),返回到達(dá)階段號(hào)。
- int awaitAdvance(int phase) 在指定階段等待(必須是當(dāng)前階段才有效)
- int awaitAdvanceInterruptibly(int phase) 階段到達(dá)觸發(fā)動(dòng)作
- int awaitAdvanceInterruptiBly(int phase,long timeout,TimeUnit unit)
- protected boolean onAdvance(int phase,int registeredParties)類似CyclicBarrier的觸發(fā)命令,通過(guò)重寫該方法來(lái)增加階段到達(dá)動(dòng)作,該方法返回true將終結(jié)Phaser對(duì)象。
2、使用
public class PhaserBatchProcessorTest {public static void main(String[] args) {final Phaser phaser = new Phaser() {//重寫該方法來(lái)增加階段到達(dá)動(dòng)作@Overrideprotected boolean onAdvance(int phase, int registeredParties) {// 參與者數(shù)量,去除主線程int staffs = registeredParties - 1;switch (phase) {case 0:System.out.println("大家都到公司了,出發(fā)去公園,人數(shù):" + staffs);break;case 1:System.out.println("大家都到公園門口了,出發(fā)去餐廳,人數(shù):" + staffs);break;case 2:System.out.println("大家都到餐廳了,開始用餐,人數(shù):" + staffs);break;}// 判斷是否只剩下主線程(一個(gè)參與者),如果是,則返回true,代表終止return registeredParties == 1;}};// 注冊(cè)主線程 ———— 讓主線程全程參與phaser.register();final StaffTask staffTask = new StaffTask();// 3個(gè)全程參與團(tuán)建的員工for (int i = 0; i < 3; i++) {// 添加任務(wù)數(shù)phaser.register();new Thread(() -> {try {staffTask.step1Task();//到達(dá)后等待其他任務(wù)到達(dá)phaser.arriveAndAwaitAdvance();staffTask.step2Task();phaser.arriveAndAwaitAdvance();staffTask.step3Task();phaser.arriveAndAwaitAdvance();staffTask.step4Task();// 完成了,注銷離開phaser.arriveAndDeregister();} catch (InterruptedException e) {e.printStackTrace();}}).start();}// 兩個(gè)不聚餐的員工加入for (int i = 0; i < 2; i++) {phaser.register();new Thread(() -> {try {staffTask.step1Task();phaser.arriveAndAwaitAdvance();staffTask.step2Task();System.out.println("員工【" + Thread.currentThread().getName() + "】回家了");// 完成了,注銷離開phaser.arriveAndDeregister();} catch (InterruptedException e) {e.printStackTrace();}}).start();}while (!phaser.isTerminated()) {int phase = phaser.arriveAndAwaitAdvance();if (phase == 2) {// 到了去餐廳的階段,又新增4人,參加晚上的聚餐for (int i = 0; i < 4; i++) {phaser.register();new Thread(() -> {try {staffTask.step3Task();phaser.arriveAndAwaitAdvance();staffTask.step4Task();// 完成了,注銷離開phaser.arriveAndDeregister();} catch (InterruptedException e) {e.printStackTrace();}}).start();}}}}static final Random random = new Random();static class StaffTask {public void step1Task() throws InterruptedException {// 第一階段:來(lái)公司集合String staff = "員工【" + Thread.currentThread().getName() + "】";System.out.println(staff + "從家出發(fā)了……");Thread.sleep(random.nextInt(5000));System.out.println(staff + "到達(dá)公司");}public void step2Task() throws InterruptedException {// 第二階段:出發(fā)去公園String staff = "員工【" + Thread.currentThread().getName() + "】";System.out.println(staff + "出發(fā)去公園玩");Thread.sleep(random.nextInt(5000));System.out.println(staff + "到達(dá)公園門口集合");}public void step3Task() throws InterruptedException {// 第三階段:去餐廳String staff = "員工【" + Thread.currentThread().getName() + "】";System.out.println(staff + "出發(fā)去餐廳");Thread.sleep(random.nextInt(5000));System.out.println(staff + "到達(dá)餐廳");}public void step4Task() throws InterruptedException {// 第四階段:就餐String staff = "員工【" + Thread.currentThread().getName() + "】";System.out.println(staff + "開始用餐");Thread.sleep(random.nextInt(5000));System.out.println(staff + "用餐結(jié)束,回家");}}
}
3、應(yīng)用場(chǎng)景
以下是一些常見的 Phaser 應(yīng)用場(chǎng)景:
- 多線程任務(wù)分配:Phaser 可以用于將復(fù)雜的任務(wù)分配給多個(gè)線程執(zhí)行,并協(xié)調(diào)線程間的合作。
- 多級(jí)任務(wù)流程:Phaser 可以用于實(shí)現(xiàn)多級(jí)任務(wù)流程,在每一級(jí)任務(wù)完成后觸發(fā)下一級(jí)任務(wù)的開始。
- 模擬并行計(jì)算:Phaser 可以用于模擬并行計(jì)算,協(xié)調(diào)多個(gè)線程間的工作。
- 階段性任務(wù):Phaser 可以用于實(shí)現(xiàn)階段性任務(wù),在每一階段任務(wù)完成后觸發(fā)下一階段任務(wù)的開始。