版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/qq_34173549/article/details/79612374
1. 閉鎖:CountDownLatch
1.1 使用場景
若有多條線程,其中一條線程需要等到其他所有線程準備完所需的資源後才能運作,這樣的情況可以使用閉鎖。
1.2 代碼實作
// 初始化閉鎖,并設定資源個數
CountDownLatch latch = new CountDownLatch(2);
Thread t1 = new Thread( new Runnable(){
public void run(){
// 加載資源1
加載資源的代碼……
// 本資源加載完後,閉鎖-1
latch.countDown();
}
} ).start();
Thread t2 = new Thread( new Runnable(){
public void run(){
// 加載資源2
資源加載代碼……
// 本資源加載完後,閉鎖-1
latch.countDown();
}
} ).start();
Thread t3 = new Thread( new Runnable(){
public void run(){
// 本線程必須等待所有資源加載完後才能執行
latch.await();
// 當閉鎖數量為0時,await傳回,執行接下來的任務
任務代碼……
}
} ).start();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
2. 同步屏障:CyclicBarrier
2.1 使用場景
若有多條線程,他們到達屏障時将會被阻塞,隻有當所有線程都到達屏障時才能打開屏障,所有線程同時執行,若有這樣的需求可以使用同步屏障。此外,當屏障打開的同時還能指定執行的任務。
2.2 閉鎖 與 同步屏障 的差別
- 閉鎖隻會阻塞一條線程,目的是為了讓該條任務線程滿足條件後執行;
- 而同步屏障會阻塞所有線程,目的是為了讓所有線程同時執行(實際上并不會同時執行,而是盡量把線程啟動的時間間隔降為最少)。
2.3 代碼實作
// 建立同步屏障對象,并制定需要等待的線程個數 和 打開屏障時需要執行的任務
CyclicBarrier barrier = new CyclicBarrier(3,new Runnable(){
public void run(){
//當所有線程準備完畢後觸發此任務
}
});
// 啟動三條線程
for( int i=0; i<3; i++ ){
new Thread( new Runnable(){
public void run(){
// 等待,(每執行一次barrier.await,同步屏障數量-1,直到為0時,打開屏障)
barrier.await();
// 任務
任務代碼……
}
} ).start();
}
3. 信号量:Semaphore
3.1 使用場景
若有m個資源,但有n條線程(n>m),是以同一時刻隻能允許m條線程通路資源,此時可以使用Semaphore控制通路該資源的線程數量。
3.2 代碼實作
// 建立信号量對象,并給予3個資源
Semaphore semaphore = new Semaphore(3);
// 開啟10條線程
for ( int i=0; i<10; i++ ) {
new Thread( new Runnbale(){
public void run(){
// 擷取資源,若此時資源被用光,則阻塞,直到有線程歸還資源
semaphore.acquire();
// 任務代碼
……
// 釋放資源
semaphore.release();
}
} ).start();
}