1. 程式人生 > >011 CountDownLatch,CyclicBarrier和Semaphore

011 CountDownLatch,CyclicBarrier和Semaphore

rgs pri exec extends new t adp 任務 stat for

CountDownLatch(閉鎖,有譯倒計數,鎖寄存):

public class CountDownLatchTest {

/**
* 比如有一個任務A,它要等待其他4個任務執行完畢之後才能執行,此時就可以利用CountDownLatch來實現這種功能了
* @param args
*/
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
new Thread(){
public void run() {
try {
System.out.println("子線程"+Thread.currentThread().getName()+"正在執行");
Thread.sleep(3000);
System.out.println("子線程"+Thread.currentThread().getName()+"執行完畢");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();

new Thread(){
public void run() {
try {
System.out.println("子線程"+Thread.currentThread().getName()+"正在執行");
Thread.sleep(3000);
System.out.println("子線程"+Thread.currentThread().getName()+"執行完畢");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();

try {
System.out.println("等待2個子線程執行完畢...");
latch.await();
System.out.println("2個子線程已經執行完畢");
System.out.println("繼續執行主線程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


CyclicBarrier(回環柵欄,有譯循環柵欄):

public class CyclicBarrierTest {

/**
* 通過它可以實現讓一組線程等待至某個狀態之後再全部同時執行,如:蓄水泄洪。我們可以用CyclicBarrier來實現。
*/

public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N);
for (int i = 1; i <= N; i++)
new Runner(barrier).start();
}

static class Runner extends Thread {
private CyclicBarrier cyclicBarrier;

public Runner(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}

@Override
public void run() {
try {
System.out.println("線程" + Thread.currentThread().getName() + "準備就位");
cyclicBarrier.await();
System.out.println("線程" + Thread.currentThread().getName() + "開始跑。");
Thread.sleep(5000);
System.out.println("線程" + Thread.currentThread().getName() + "到達終點。");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}

}
}
}

Semaphore(信號量):

public class SemaphoreTest {
/**
* 假設一個工廠有8個工人,只有5臺機器,一臺機器同時只能被一個工人使用,只有使用完了,其他工人才能繼續使用。那麽我們就可以通過Semaphore來實現
*
* @param args
*/
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(5); //機器數目
int workerNum = 8; //工人數
for (int i = 1; i <= workerNum; i++)
new Worker(i, semaphore).start();
}

static class Worker extends Thread {
private int num;
private Semaphore semaphore;

public Worker(int num, Semaphore semaphore) {
this.num = num;
this.semaphore = semaphore;
}

@Override
public void run() {
try {
semaphore.acquire();
System.out.println("工人" + this.num + "占用一個機器在生產...");
Thread.sleep(2000);
System.out.println("工人" + this.num + "釋放出機器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


Exchanger(交易):
public class ExchangerTest {

/**
* 兩個人約定交易地點,交易必須完成,不見不散,可以用exchanger來完成。
* @param args
*/
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final Exchanger exchanger = new Exchanger();
Runnable runnable1 = new Runnable() {
@Override
public void run() {
try {
String data1 = "data one";
System.out.println("線程" + Thread.currentThread().getName() + "正在把數據" + data1 + "換出去");
Thread.sleep((long) (Math.random() * 1000));
String data2 = (String) exchanger.exchange(data1);
System.out.println("線程" + Thread.currentThread().getName() + "換回的數據為" + data2);
} catch (Exception e) {
System.out.println(e);
}
}
};

Runnable runnable2 = new Runnable() {
@Override
public void run() {
try {
String data1 = "data two";
System.out.println("線程" + Thread.currentThread().getName() + "正在把數據" + data1 + "換出去");
Thread.sleep((long) (Math.random() * 10000));
String data2 = (String) exchanger.exchange(data1);
System.out.println("線程" + Thread.currentThread().getName() + "換回的數據為" + data2);
} catch (Exception e) {
System.out.println(e);
}
}
};
service.execute(runnable1);
service.execute(runnable2);
}


}

011 CountDownLatch,CyclicBarrier和Semaphore