等待喚醒機制

2021-07-05 13:34:06 字數 2838 閱讀 3615

等待喚醒機制是多執行緒通訊中的概念,首先我們要先了解什麼是執行緒間的通訊

概念:多個執行緒都在處理同乙個資源,但是處理的任務不一樣。此時就需要多執行緒之間進行通訊,保證同一資源的正確性。

剖析:通過多執行緒間的通訊的經典例項來進一步了解多執行緒間通訊的概念

經典例項:生產者,消費者

1、首先通過乙個簡單的示意圖來了解生產者和消費者的概念

2、用**例項進一步說明

需求:生產者生產乙個麵包後,放入容器,只有當消費者消費後,生產者才能開始生產,以此類推。

根據圖示可分析生成者和消費者是兩個不同的任務,而操作的確是相同的資源,所以必須進行通訊。

首先建立生產者、消費者、資源三個類來描述事物。

/**

* @author zqx

* 描述資源

*/public class resource

// 提供給生產者生產商品的方法

public void setname(string name)

}

/**

* @author zqx 生產者任務

*/public class producer implements runnable

@override

public void run()

}

/**

* @author zqx 消費者任務

*/public class custemer implements runnable

@override

public void run()

}

/**

* @author zqx

* 測試類

*/public class producercustemer

}

由於執行緒執行的隨機性,程式將會出現以下安全問題:

1、生產者沒生產出麵包時,消費者已經消費該麵包。 生產消費順序問題。

2、生產者生產完畢後,消費者沒有消費之前,生產者又生產了。

3、消費者連續消費同一麵包多次。

如果要解決問題1,可以使用同步。在這裡選擇使用同步函式的方式解決。但是加入同步後問題2和問題3依然存在。

如果要解決問題2和問題3,就要用到多執行緒中的等待喚醒機制。那麼什麼是等待喚醒機制呢?

首先分析出現問題2和問題3的原因,可參照上文中的進行理解。

加入同步後,生產者拿到鎖之後生產麵包,消費者處於臨時阻塞狀態,當生產者釋放鎖的時候,由於cpu執行的隨機性,生產者和消費者都有可能拿到鎖。如果生產者再次拿到鎖就會出現安全問題。如何解決?

定義乙個布林型別flag標記容器中是否有麵包。生產和消費前首先判斷flag的值,如果為flag為false,則凍結消費者執行緒,如果flag為true,則凍結生產者。初始化flag的值為false ,生產者生產麵包後,把flag的值置為true,並喚醒消費者 ; 當消費者消費完麵包時,把flag的值置為false,並喚醒生產者。這就是多執行緒的等待喚醒機制

凍結:wait():該方法可以讓執行緒處於凍結狀態,並將執行緒臨時儲存到執行緒池中。

喚醒:notify():喚醒指定執行緒池中的任意乙個執行緒。只喚醒乙個。

notifyall():喚醒指定執行緒池中的所有執行緒

上述概念用簡圖來表示 :

} // 提供給生產者生產商品的方法

public synchronized void set(string name) catch (interruptedexception e)

} else

}}

生產者任務public class producer implements runnable 

@override

public void run()

}

public class custemer implements runnable 

@override

public void run()

}

public class producercustemer 

}

1、wait()、notify() 這樣的方法必須用在同步當中,離開同步是沒有意義的。原因:wait() notity()這樣的方法本身就是用來操作同步鎖上的執行緒的狀態的,鎖也稱之為監視器。

在使用這些方法時,必須標識它們所屬的鎖,標識方式就是 鎖物件.wait();鎖物件.notify(); 鎖物件.notifyall();

相同鎖的notify(),可以喚醒相同鎖的wait();

上述例子中使用的鎖是this

通過查閱api,會發現wait()這種方法定義在objec類t當中,而沒定義在thread類中,就是因為 鎖物件是任意物件。

等待喚醒機制

等待喚醒機制 涉及的方法 wait 將同步中的執行緒處於凍結狀態。釋放了執行權,釋放了資格。同時將執行緒物件儲存到執行緒池中。notify 喚醒執行緒池中某乙個等待執行緒。notifyall 喚醒的是執行緒池中的所有執行緒。注意 1 這些方法都需要定義在同步中。2 因為這些方法必須要標示所屬的鎖。你...

執行緒等待喚醒機制

等待喚醒機制 乙個執行緒在工作時發現某些條件不滿足了,這時可以釋放掉鎖,並暫停工作。目的是讓另乙個執行緒插入進來,進行條件的補給 後進入的執行緒在補足條件後,可以進行 喚醒 將之前所有等待的執行緒喚醒,讓他們繼續工作,然後自己退出。喚醒之後執行的 system.out.println 包子已經做好了...

等待與喚醒機制

1 執行緒間通訊 概念 多執行緒在處理同乙個資源,但是處理的動作卻不相同。為什麼處理執行緒間通訊?多執行緒併發執行時,在預設情況下cpu是隨機切換執行緒的,當我們需要多執行緒來共同完成一件任務,並且我們希望他們有規律的執行,那麼多執行緒之間需要一些協調通訊,以此來幫我們達到多執行緒共同操作乙份資料。...