CountDownLatch、CyclicBarrier和Semaphore使用
阿新 • • 發佈:2018-03-16
post i++ release 正在 多少 wait rup int args
- CountDownLatch
CountDownLatch是用來線程計數的。等待一組線程全部執行完後再本線程繼續執行。如:A線程需要等待B、C和D(由初始化CountDownLatch參數覺得等待多少個線程)線程執行完後再執行。
主要的方法:
// 構造方法,count決定等待多少個線程 public CountDownLatch(int count) // 等待線程完成數減1 public void countDown() // 調用await本線程會掛起,當等待線程未完成數為0,即countDown調用次數等於構造方法參數值時會被喚醒 public void await() public boolean await(long timeout, TimeUnit unit)
以下是CountDownLatch的用法:
public class CountDownLatchTest { public static void main(String[] args) { final CountDownLatch countDownLatch = new CountDownLatch(2); for (int i = 0; i < 2; i++) { new Thread(() -> { try { String name = Thread.currentThread().getName(); System.out.println("子線程" + name + "正在運行中......"); TimeUnit.SECONDS.sleep(5); System.out.println("子線程" + name + "執行完畢"); countDownLatch.countDown(); } catch (Exception e) { e.printStackTrace(); } }).start(); } try { System.out.println("======等待兩個子線程執行完畢"); // 只有子線程執行完畢個數等於CountDownLatch初始化個數才會繼續執行await後面代碼 countDownLatch.await(); System.out.println("兩個子線程都執行完畢!!!!!!"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主線程繼續執行中。。。。。。。。"); } }
結果:
子線程Thread-0正在運行中......
======等待兩個子線程執行完畢
子線程Thread-1正在運行中......
子線程Thread-1執行完畢
子線程Thread-0執行完畢
兩個子線程都執行完畢!!!!!!
主線程繼續執行中。。。。。。。。
- CyclicBarrier
CyclicBarrier 設置一個障礙點,讓同組線程到達改點的線程等待本組未達到該點的線程,同組全部線程到達該點才越過障礙物釋放資源,讓其它組循環利用該對象。
主要方法:
// 構造方法設置同組線程數 public CyclicBarrier(int parties) // 構造方法設置同組線程數;全部達到障礙物時執行barrierAction函數 public CyclicBarrier(int parties, Runnable barrierAction) // 某個線程調用await時掛起,需要等同組所有線程到達才能喚醒 public int await() throws InterruptedException, BrokenBarrierException
以下是 CyclicBarrier 的用法:
/**
* Created on 18/3/15 14:40.
*
* @author wolf
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
int n = 3;
CyclicBarrier barrier = new CyclicBarrier(n);
for (int i = 0; i < 3; i++) {
new Worker(barrier).start();
}
try {
TimeUnit.SECONDS.sleep(6);
System.out.println("--------討厭的循環利用分割線------------");
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < n; i++) {
new Worker(barrier).start();
}
}
static class Worker extends Thread {
private CyclicBarrier barrier;
public Worker(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
String name = Thread.currentThread().getName();
System.out.println("線程 " + name + " 正在執行任務.......");
try {
int time = RandomUtils.nextInt(1, 5);
TimeUnit.SECONDS.sleep(time);
System.out.println("線程 " + name + " 執行任務完畢!!!用時:" + time);
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("線程 " + name + " 全部耗時:"+(System.currentTimeMillis()-startTime));
}
}
}
- Semaphore
Semaphore 通過名字我們就知道這個計算信號量,也就是控制獲取資源的許可證。
主要的方法:
// 構造方法設置可用資源的數量,即許可證的數量
public Semaphore(int permits)
// 構造方法設置可用資源的數量,即許可證的數量,fair 是否公平獲得許可證,默認是先來後到公平的
public Semaphore(int permits, boolean fair)
// 同步獲取許可證,
public void acquire() throws InterruptedException
// 嘗試獲取許可證,結果直接返回
public boolean tryAcquire()
// 嘗試獲取許可證,結果等待時間超時直接返回
public boolean tryAcquire(long timeout, TimeUnit unit)
// 釋放許可證,可給其它等待線程使用
public void release()
以下是 Semaphore 用法:
public class SemaphoreTest {
public static void main(String[] args) {
int no = 5;
Semaphore semaphore = new Semaphore(2);
for (int i = 0; i < no; i++) {
new Worker(i, semaphore).start();
}
}
static class Worker extends Thread {
private int no;
private Semaphore semaphore;
public Worker(int no, Semaphore semaphore) {
this.no = no;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
long startTime = System.currentTimeMillis();
semaphore.acquire();
System.out.println("worker " + this.no + " 獲取許可證,開始工作....");
int time = RandomUtils.nextInt(1, 5);
TimeUnit.SECONDS.sleep(time);
semaphore.release();
System.out.println("worker " + this.no + " 完成工作,釋放許可證!耗時:" + (System.currentTimeMillis() - startTime));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
CountDownLatch、CyclicBarrier和Semaphore使用