【Java】【多執行緒】兩個執行緒間的通訊、wait、notify、notifyAll
等待喚醒機制:wait()、notify()
1、什麼時候需要通訊
- 多個執行緒併發執行時, 在預設情況下CPU是隨機切換執行緒的
- 如果我們希望他們有規律的執行, 就可以使用通訊, 例如每個執行緒執行一次列印,輪流執行
2、怎麼通訊
- 如果希望執行緒等待, 就呼叫wait()
- 如果希望喚醒等待的執行緒, 就呼叫notify();
- 這兩個方法必須在同步程式碼中執行, 並且使用同步鎖物件來呼叫,this
public class Demo1_Notify {
/**
* @param args
* 等待喚醒機制
*/
public static void main(String[] args) {
final Printer p = new Printer();
new Thread() { //執行緒1
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() { //執行緒2
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
//等待喚醒機制
class Printer {
private int flag = 1;
public void print1() throws InterruptedException {
synchronized(this) {
if(flag != 1) {
this.wait(); //當前執行緒等待,直到被喚醒
}
System.out.print("黑");
System.out.print("馬");
System.out.print("程");
System.out.print("序");
System.out.print("員");
System.out.print("\r\n");
flag = 2;
this.notify(); //隨機喚醒單個等待的執行緒,此時仍然具有執行權,上面使得執行緒進入等待
}
}
public void print2() throws InterruptedException {
synchronized(this) {
if(flag != 2) {
this.wait();
}
System.out.print("傳");
System.out.print("智");
System.out.print("播");
System.out.print("客");
System.out.print("\r\n");
flag = 1;
this.notify();
}
}
}
2、多個執行緒通訊的問題
- notify()方法是隨機喚醒一個執行緒
- notifyAll()方法是喚醒所有執行緒
- JDK5之前無法喚醒指定的一個執行緒
- 如果多個執行緒之間通訊, 需要使用notifyAll()通知所有執行緒, 用while來反覆判斷條件
public class Demo2_NotifyAll {
/**
* @param args
*/
public static void main(String[] args) {
final Printer2 p = new Printer2();
new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.print3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
class Printer2 {
private int flag = 1;
public void print1() throws InterruptedException {
synchronized(this) {
while(flag != 1) {
this.wait(); //當前執行緒等待
}
System.out.print("黑");
System.out.print("馬");
System.out.print("程");
System.out.print("序");
System.out.print("員");
System.out.print("\r\n");
flag = 2;
//this.notify(); //隨機喚醒單個等待的執行緒
this.notifyAll();
}
}
public void print2() throws InterruptedException {
synchronized(this) {
while(flag != 2) {
this.wait(); //執行緒2在此等待
}
System.out.print("傳");
System.out.print("智");
System.out.print("播");
System.out.print("客");
System.out.print("\r\n");
flag = 3;
//this.notify();
this.notifyAll();
}
}
public void print3() throws InterruptedException {
synchronized(this) {
while(flag != 3) {
this.wait(); //執行緒3在此等待,if語句是在哪裡等待,就在哪裡起來
//while迴圈是迴圈判斷,每次都會判斷標記
}
System.out.print("i");
System.out.print("t");
System.out.print("h");
System.out.print("e");
System.out.print("i");
System.out.print("m");
System.out.print("a");
System.out.print("\r\n");
flag = 1;
//this.notify();
this.notifyAll();
}
}
}
三、wait()和notify()的通常用法
Java多執行緒開發中,我們常用到wait()和notify()方法來實現執行緒間的協作,簡單的說步驟如下:
1. A執行緒取得鎖,執行wait(),釋放鎖;
2. B執行緒取得鎖,完成業務後執行notify(),再釋放鎖;
3. B執行緒釋放鎖之後,A執行緒取得鎖,繼續執行wait()之後的程式碼;
注意:wait(long timeout):讓當前執行緒處於“等待(阻塞)狀態”,“直到其他執行緒呼叫此物件的notify()方法或 notifyAll() 方法,或者超過指定的時間量”,當前執行緒被喚醒(進入“就緒狀態”)。
四、通訊需要注意的幾點:
1、在同步程式碼塊中,用哪個物件鎖,就用哪個物件呼叫wait方法:this.wait()
2、為什麼wait方法和notify方法定義在Object這類中?因為鎖物件可以是任意物件,Object是所有的類的基類,所以wait方法和notify方法需要定義在Object這個類中
相關文章
- 執行緒間的同步與通訊(2)——wait, notify, notifyAll執行緒AI
- Java多執行緒8:wait()和notify()/notifyAll()Java執行緒AI
- 執行緒間協作——wait、notify、notifyAll執行緒AI
- Java多執行緒/併發11、執行緒同步通訊:notify、waitJava執行緒AI
- Java多執行緒中的wait/notify通訊模式Java執行緒AI模式
- java多執行緒wait notify joinJava執行緒AI
- java多執行緒5:執行緒間的通訊Java執行緒
- Java通過wait()和notifyAll()方法實現執行緒間的通訊JavaAI執行緒
- Java多執行緒-執行緒通訊Java執行緒
- Java多執行緒的wait()和notify()例子Java執行緒AI
- java多執行緒間的通訊Java執行緒
- java多執行緒 wait() notify()簡單使用Java執行緒AI
- 多執行緒中的wait與notify執行緒AI
- Java多執行緒學習——執行緒通訊Java執行緒
- 多執行緒之間通訊及執行緒池執行緒
- Java多執行緒 -- wait() 和 notify() 使用入門Java執行緒AI
- 深入執行緒的wait()/notify()執行緒AI
- 徹底明白Java的多執行緒-執行緒間的通訊(2)(轉)Java執行緒
- 徹底明白Java的多執行緒-執行緒間的通訊(1)(轉)Java執行緒
- Java多執行緒學習(3)執行緒同步與執行緒通訊Java執行緒
- Java多執行緒中wait 和 notify 方法理解Java執行緒AI
- 多執行緒之間的通訊執行緒
- 執行緒4--執行緒間通訊執行緒
- 多執行緒,執行緒類三種方式,執行緒排程,執行緒同步,死鎖,執行緒間的通訊,阻塞佇列,wait和sleep區別?執行緒佇列AI
- java多執行緒:執行緒間通訊——生產者消費者模型Java執行緒模型
- 執行緒間的通訊執行緒
- Android小知識-Java多執行緒相關(執行緒間通訊)上篇AndroidJava執行緒
- Java多執行緒學習(五)執行緒間通訊知識點補充Java執行緒
- Java多執行緒——獲取多個執行緒任務執行完的時間Java執行緒
- Swift多執行緒:使用Thread進行多執行緒間通訊,協調子執行緒任務Swift執行緒thread
- Java執行緒通訊Java執行緒
- 說說Java執行緒間通訊Java執行緒
- Java多執行緒——執行緒Java執行緒
- 多執行緒Demo學習(執行緒的同步,簡單的執行緒通訊)執行緒
- java多執行緒基礎篇(wait、notify、join、sleep、yeild方法)Java執行緒AI
- Java多執行緒學習(四)等待/通知(wait/notify)機制Java執行緒AI
- Java多執行緒-執行緒中止Java執行緒
- Java多執行緒——執行緒池Java執行緒