Cyclic:循環的,有週期性的
Barrier:障礙物,屏障
Latch:門閂,閂鎖
講解CyclicBarrier的功能時,通過輔助畫圖的方式說明,效果會更好。
\ /
\ | /
------------------------三個線程幹完各自的任務,在不同的時刻到達集合點後,就可以接着忙各自的工作去了,再到達新的集合點,再去忙各自的工作,
到達集合點了用CyclicBarrier對象的await方法表示。
/ | \
/ | \
-------------------
爲什麼幾個人能碰到一起,說白了,就是大家都把手頭這一階段的工作做完了,就可以碰到一起了。譬如,我下樓等方老師,就是等他手頭工作做完了,他到達了要集合的狀態,就集合了。
-----------------CyclicBarrier的代碼:---------------------------------
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3);
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() +
"即將到達集合地點1,當前已有" + (cb.getNumberWaiting()+1) + "個已經到達," + (cb.getNumberWaiting()==2?"都到齊了,繼續走啊":"正在等候"));
cb.await();
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() +
"即將到達集合地點2,當前已有" + (cb.getNumberWaiting()+1) + "個已經到達," + (cb.getNumberWaiting()==2?"都到齊了,繼續走啊":"正在等候"));
cb.await();
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() +
"即將到達集合地點3,當前已有" + (cb.getNumberWaiting() + 1) + "個已經到達," + (cb.getNumberWaiting()==2?"都到齊了,繼續走啊":"正在等候"));
cb.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
-----------------CountdownLatch的代碼:---------------------------------
package cn.itcast.day3.thread;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountdownLatchTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CountDownLatch cdOrder = new CountDownLatch(1);
final CountDownLatch cdAnswer = new CountDownLatch(3);
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
System.out.println("線程" + Thread.currentThread().getName() +
"正準備接受命令");
cdOrder.await();
System.out.println("線程" + Thread.currentThread().getName() +
"已接受命令");
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() +
"迴應命令處理結果");
cdAnswer.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
try {
Thread.sleep((long)(Math.random()*10000));
System.out.println("線程" + Thread.currentThread().getName() +
"即將發佈命令");
cdOrder.countDown();
System.out.println("線程" + Thread.currentThread().getName() +
"已發送命令,正在等待結果");
cdAnswer.await();
System.out.println("線程" + Thread.currentThread().getName() +
"已收到所有響應結果");
} catch (Exception e) {
e.printStackTrace();
}
service.shutdown();
}
}
---------------------------ExchangerTest-------------------------
講解Exchanger的比喻:好比兩個毒販要進行交易,一手交錢、一手交貨,不管誰先來到接頭地點後,就處於等待狀態了,當另外一方也到達了接頭地點(所謂到達接頭地點,也就是到到達了準備接頭的狀態)時,兩者的數據就立即交換了,然後就又可以各忙各的了。
exchange方法就相當於兩手高高舉着待交換物,等待人家前來交換,一旦人家到來(即人家也執行到exchange方法),則兩者立馬完成數據的交換。
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExchangerTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final Exchanger exchanger = new Exchanger();
service.execute(new Runnable(){
public void run() {
try {
String data1 = "zxx";
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){
}
}
});
service.execute(new Runnable(){
public void run() {
try {
String data1 = "lhm";
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){
}
}
});
}
}
總結:這個程序雖然簡單,但實實在在解決了一種應用問題,這就是新技術帶來的價值,新技術的價值就猶如一個億萬富豪得了不治之症,目前沒有什麼藥品可以醫治,你發現了一種新葯專門治這種病,你對他說,把他的億萬家產給你,你就把藥片給他,你說他幹不幹?他絕對會幹!這就是新葯和新技術的威力嘛!新技術在關鍵時刻總能發揮特殊的作用,就看你遇到沒遇到這種關鍵的時刻,一旦遇到,那就能產生很大價值了。
java其他同步工具類
lCyclicBarrier
Ø表示大家彼此等待,大家集合好後纔開始出發,分散活動後又在指定地點集合碰面,這就好比整個公司的人員利用週末時間集體郊遊一樣,先各自從家出發到公司集合後,再同時出發到公園遊玩,在指定地點集合後再同時開始就餐,…。
lCountDownLatch
Ø猶如倒計時計數器,調用CountDownLatch對象的countDown方法就將計數器減1,當計數到達0時,則所有等待者或單個等待者開始執行。這直接通過代碼來說明CountDownLatch的作用,這樣學員的理解效果更直接。
Ø可以實現一個人(也可以是多個人)等待其他所有人都來通知他,可以實現一個人通知多個人的效果,類似裁判一聲口令,運動員同時開始奔跑,或者所有運動員都跑到終點後裁判纔可以公佈結果,用這個功能做百米賽跑的遊戲程序不錯哦!還可以實現一個計劃需要多個領導都簽字後才能繼續向下實施的情況。
lExchanger
Ø用於實現兩個人之間的數據交換,每個人在完成一定的事務後想與對方交換數據,第一個先拿出數據的人將一直等待第二個人拿着數據到來時,才能彼此交換數據。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.