執行緒間通訊:
其實就是多個執行緒在操作同乙個資源,但是操作的動作不同
等待喚醒機制:
wait:
notify:
notifyall;
都是用在同步中,因為要對持有監視器(鎖)的執行緒操作。
所以要是用在同步中,因為只有同步才具有鎖。
等待喚醒必須是同乙個鎖,而鎖可以是任意物件,所以可以被任意物件呼叫的方法定義在object
類中。生產者消費者例項(多個生產者,多個消費者):
class producerconsumerdemo
}class resourcecatch(exception e){}
this.name = name+"--"+count++;
system.out.println(thread.currentthread().getname()+"....生產者
..."+this.name);
flag = true;
this.notify();
}public synchronized void out()catch(exception e){}
system.out.println(thread.currentthread().getname()+"...消費者
..."+this.name);
flag = false;
this.notify();}}
//生產者
class producer implements runnable
public void run()}}
//消費者
class consumer implements runnable
public void run()}}
此程式容易出現多次生產,單次消費。或單詞生產多次消費的問題。
問題產生原因:
以上程式塊中
設生產者:thread-0
,thread-1
消費者:
thread-2
,thread-3
0執行緒先進入,
flag=true,1
執行緒進入,因
flag=true
,等待0執行緒再次進入,因
flag=true
,等待。
2執行緒進入,
flag=false
,並喚醒了
0執行緒,0,
1執行緒已經路過判斷關卡,因此直接執行**,
flag=true,並隨機喚醒了
1執行緒;
1執行緒已經經過判斷關卡,因此直接執行**,所以會出現兩次生產
一次消費的問題。
如果改用while
(flag
)迴圈判斷,則解決了執行緒只判斷一次便通過的問題,但容易出現無限等待的問題,
就是幾個執行緒互相等待。如果不懂可以讓**跑起來試試。
問題產生原因:
flag=false,
3執行緒進入,等待。
0執行緒進入,
flag=true,1
執行緒進入,因
flag=true
,等待0執行緒再次進入,因
flag=true
,等待。
2執行緒進入,
flag=false
,隨機釋放
3執行緒,
2執行緒繼續執行,因
flag=false
,結果處於等待。
因flag=false,3
執行緒也處於等待,因此所有的執行緒全部等待,無人啟用
解決問題:
既不能讓同步**塊只判斷一次便通過,又不能讓程式進入無線等待中。
綜上,採用notifyall()
方法,將所有的執行緒全部喚醒,而不是僅僅只喚醒乙個。這樣一來
既可以無限判斷,不至於有漏網之魚,又免去無限等待的痛苦。
修改如下:
public synchronized void set(string name)catch(exception e){}
this.name = name+"--"+count++;
system.out.println(thread.currentthread().getname()+"....生產者
..."+this.name);
flag = true;
this.notifyall();
}public synchronized void out()catch(exception e){}
system.out.println(thread.currentthread().getname()+"...消費者
..."+this.name);
flag = false;
this.notifyall();
}jdk5.0公升級以後的多執行緒通訊
其中用到了 lock
類, condition
類;以下**與
lock
類api
中示例**相似
private lock lock = new lock();
condition condition_pro = lock.newcondition();
condition condition_con = lock.newcondition();
//生產者生產方法
public void set(string name)throws interruptedexceptionfinally
}//消費者消費方法
public void out()throws interruptedexceptionfinally
}jdk5.0公升級後的新特性:
jdk1.5中提供了多執行緒公升級解決方案。
將同步synchronized
替換成了顯示的
lock
操作。將object
中的wait
,notify
,notifyall
,替換成了
condition
物件,該物件可以通過
lock
鎖進行獲取。
如何讓執行緒停止:
原理:只有一種,run
方法結束。
開啟多執行緒執行,執行**通常是迴圈結構。
只要控制住迴圈,就可以讓run
方法結束,也就是執行緒結束。
特殊情況:
當執行緒處於了凍結狀態,就不會讀取到結束標記,執行緒就不會結束。
此時只能強制讓執行緒恢復到執行狀態中來,interrupt()
就是具有這樣功能的方法。
thread類中的一些常用方法:
interrupt()中斷方法:該方法是結束執行緒的凍結狀態,使執行緒回到執行狀態來。
setdaemon(boolean on):將該執行緒標記為守護執行緒或使用者執行緒
(後台執行緒
)。此方法必須在開啟執行緒之前呼叫,具體可以寫例項試試
join(): 該方法用於執行緒獲得
cpu(
執行權)
,直到該執行緒終止。
join例子:
demo d = new demo();//建立乙個
runnable
子類物件
thread t1 = new thread(d);
thread t2 = new thread(d);
t1.start();
//此處
t1執行緒呼叫
join
方法,獲得
main
執行緒的執行權,
main
執行緒暫停服務,直到
t1執行緒執行結束
//由於
main
執行緒失去了執行權,所以
t2執行緒還沒有被開啟。
t1.join();
t2.start();
優先順序問題:
demo d = new demo();//建立乙個
runnable
子類物件
thread t1 = new thread(d);
thread t2 = new thread(d);
t1.start();
//設定執行緒優先順序
t1.setpriority(thread.max_priority);
t2.start();
yield() :暫停當前正在執行的執行緒物件,並執行其他執行緒。
稍微暫停當前執行緒,並執行其他執行緒,放在run
函式中,有使得執行緒交叉執行的效果;
Java執行緒間通訊
要求用子執行緒和主線程實現 子執行緒輸出20次,主線程輸出50次,然後再子執行緒輸出20次,主線程輸出50次,如此迴圈20次 1 建立乙個用於輸出的業務類 business class business catch interruptedexception e for int i 0 i 10 i ...
java執行緒間通訊
執行緒間進行輸入 輸出通訊最常用的方式是 管道 方式。乙個執行緒從管道一端寫入資料,另乙個執行緒從管道另一端讀出資料。public class pipedio class pipesender extends thread public void run catch ioexception e cl...
Java執行緒間通訊
對於我們的銀行賬戶,兩個執行緒之間並沒有聯絡,這就會出現餘額不足但是還能取錢的狀況,為了解決這個問題,我們就使用執行緒間通訊來解決 wait 方法 中斷方法的執行,使執行緒等待 notify 方法 喚醒處於等待的某一線程,使其等待結束 notifyall 方法 喚醒處於等待的所有執行緒,使其等待結束...