昨天介紹了 CountDownLatch 類別,它主要用來等待所有的執行緒都執行完成之後程式才會繼續往下的執行。今天介紹另外一個在 java.util.concurrent package 下的 CyclicBarrier 類別,它主要可以讓執行緒進行等待的狀態,等到所有的執行緒都準備好了之後,所有的執行緒程式才會開始的進行執行,以下是使用 CyclicBarrier 類別的 Sample Code:
import java.util.concurrent.CyclicBarrier;
public class CyclicExampleThread implements Runnable {
private CyclicBarrier cyclicBarrier;
public CyclicExampleThread(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
String currentThread = Thread.currentThread().getName();
System.out.println("pre run thread, current thread is " + currentThread);
try {
this.cyclicBarrier.await();
System.out.println("finish thread, current thread is " + currentThread);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
以上是執行緒的程式主要會在建構子裡面設定 CyclicBarrier 從主程式傳進來的物件,然後在 run 的方法裡面會先得到目前執行的執行緒名稱,然後後先印出 pre run thread ...的字串。之後會進入等待的狀態,等到所有的執行緒都準備好之後才繼續往下執行,印出 finish thread...的字串。以下是主程式的程式:
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String args[]) {
ExecutorService es = Executors.newFixedThreadPool(5);
try {
CyclicBarrier cet = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
es.execute(new CyclicExampleThread(cet));
}
} catch(Exception e) {
throw new RuntimeException(e);
} finally {
es.shutdown();
}
}
}
在主程式裡會建立執行緒 pool,然後建立 CyclicBarrier instance,在建構子裡面給要等待 5 個執行緒都準備好之後,執行緒的程式才會繼續的往下執行,以下是執行的結果:
pre run thread, current thread is pool-1-thread-1
pre run thread, current thread is pool-1-thread-3
pre run thread, current thread is pool-1-thread-4
pre run thread, current thread is pool-1-thread-2
pre run thread, current thread is pool-1-thread-5
finish thread, current thread is pool-1-thread-1
finish thread, current thread is pool-1-thread-3
finish thread, current thread is pool-1-thread-5
finish thread, current thread is pool-1-thread-2
finish thread, current thread is pool-1-thread-4
從執行的結果裡可以看到 pref run thread 的字串都會先印出,之後等到所有的執行緒程式都 start 準備好了之後,才會把 finish thread 的字串印出來。