5: Synchronizer:同步裝置
Java 5.0里新加了4個協(xié)調線程間進程的同步裝置,它們分別是Semaphore, CountDownLatch, CyclicBarrier和Exchanger.
Semaphore:
用來管理一個資源池的工具,Semaphore可以看成是個通行證,線程要想從資源池拿到資源必須先拿到通行證,Semaphore提供的通行證數(shù)量和資源池的大小一致。如果線程暫時拿不到通行證,線程就會被阻斷進入等待狀態(tài)。以下是一個例子:
public class Pool {
ArrayList pool = null;
Semaphore pass = null;
public Pool(int size){
//初始化資源池
pool = new ArrayList();
for(int i=0; i
pool.add("Resource "+i);
}
//Semaphore的大小和資源池的大小一致
pass = new Semaphore(size);
}
public String get() throws InterruptedException{
//獲取通行證,只有得到通行證后才能得到資源
pass.acquire();
return getResource();
}
public void put(String resource){
//歸還通行證,并歸還資源
pass.release();
releaseResource(resource);
}
private synchronized String getResource() {
String result = pool.get(0);
pool.remove(0);
System.out.println("Give out "+result);
return result;
}
private synchronized void releaseResource(String resource) {
System.out.println("return "+resource);
pool.add(resource);
}
}
SemaphoreTest:
public class SemaphoreTest {
public static void main(String[] args){
final Pool aPool = new Pool(2);
Runnable worker = new Runnable() {
public void run() {
String resource = null;
try {
//取得resource
resource = aPool.get();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
//用resource做工作
System.out.println("I worked on "+resource);
//歸還resource
aPool.put(resource);
}
};
ExecutorService service = Executors.newCachedThreadPool();
for(int i=0; i<20; i++){
service.submit(worker);
}
service.shutdown();
}
}
CountDownLatch:
CountDownLatch是個計數(shù)器,它有一個初始數(shù),等待這個計數(shù)器的線程必須等到計數(shù)器倒數(shù)到零時才可繼續(xù)。比如說一個Server啟動時需要初始化4個部件,Server可以同時啟動4個線程去初始化這4個部件,然后調用CountDownLatch(4).await()阻斷進入等待,每個線程完成任務后會調用一次CountDownLatch.countDown()來倒計數(shù), 當4個線程都結束時CountDownLatch的計數(shù)就會降低為0,此時Server就會被喚醒繼續(xù)下一步操作。CountDownLatch的方法主要有:
await():使調用此方法的線程阻斷進入等待
countDown(): 倒計數(shù),將計數(shù)值減1
getCount(): 得到當前的計數(shù)值
CountDownLatch的例子:一個server調了三個ComponentThread分別去啟動三個組件,然后server等到組件都啟動了再繼續(xù)。
public class Server {
public static void main(String[] args) throws InterruptedException{
System.out.println("Server is starting.");
//初始化一個初始值為3的CountDownLatch
CountDownLatch latch = new CountDownLatch(3);
//起3個線程分別去啟動3個組件
ExecutorService service = Executors.newCachedThreadPool();
service.submit(new ComponentThread(latch, 1));
service.submit(new ComponentThread(latch, 2));
service.submit(new ComponentThread(latch, 3));
service.shutdown();
//進入等待狀態(tài)
latch.await();
//當所需的三個組件都完成時,Server就可繼續(xù)了
System.out.println("Server is up!");
}
}
public class ComponentThread implements Runnable{
CountDownLatch latch;
int ID;
/** Creates a new instance of ComponentThread */
public ComponentThread(CountDownLatch latch, int ID) {
this.latch = latch;
this.ID = ID;
}
public void run() {
System.out.println("Component "+ID + " initialized!");
//將計數(shù)減一
latch.countDown();
}
}
運行結果:
CyclicBarrier:
CyclicBarrier類似于CountDownLatch也是個計數(shù)器,不同的是CyclicBarrier數(shù)的是調用了CyclicBarrier.await()進入等待的線程數(shù),當線程數(shù)達到了CyclicBarrier初始時規(guī)定的數(shù)目時,所有進入等待狀態(tài)的線程被喚醒并繼續(xù)。CyclicBarrier就象它名字的意思一樣,可看成是個障礙,所有的線程必須到齊后才能一起通過這個障礙。CyclicBarrier初始時還可帶一個Runnable的參數(shù),此Runnable任務在CyclicBarrier的數(shù)目達到后,所有其它線程被喚醒前被執(zhí)行。
相關推薦:計算機等級考試二級Java經(jīng)典算法大全匯總北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |