java執行緒間通訊

2021-06-11 16:59:56 字數 4204 閱讀 7402

執行緒間通訊:

其實就是多個執行緒在操作同乙個資源,但是操作的動作不同

等待喚醒機制:

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 方法 喚醒處於等待的所有執行緒,使其等待結束...