您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何使用wait() 和notify() 機制來完成睡眠和踢,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
使用 wait() 和 notify() 機制來完成“睡眠”和“踢”。實際的消費者工作由 OnConsume(Object) 方法處理,如清單 3 所示:
清單 3. 喚醒和通知 Consumer
/**
* Add an object to the Consumer.
* This is the entry point for the producer.
* After the item is added, the Consumer´s thread
* will be notified.
*
* @param the object to be ´consumed´ by this consumer
*/
public void add(Object o)
{
_queue.add(o);
kickThread();
}
/**
* Wake up the thread (without adding new stuff to consume)
*
*/
public void kickThread()
{
if (!this._thread.isInterrupted())
{
synchronized(_waitForJobsMonitor)
{
_waitForJobsMonitor.notify();
}
}
}
示例:MessagesProcessor
為了向您展示 Consumer 類是如何工作的,我們將使用一個簡單示例。MessagesProcessor 類以異步方式處理進入的消息(也就是說,不干擾調用線程)。其工作是在每個消息到來時打印它。MessagesProcessor 具有一個處理到來的消息作業的內部 Consumer。當新作業進入空隊列時,Consumer 調用 processMessage(String) 方法來處理它,如清單 4 所示:
清單 4. MessagesProcessor 類
class MessagesProcessor
{
String _name;
// anonymous inner class that supplies the consumer
// capabilities for the MessagesProcessor
private Consumer _consumer = new Consumer()
{
// that method is called on each event retrieved
protected void onConsume(Object o)
{
if (!(o instanceof String))
{
System.out.println("illegal use, ignoring");
return;
}
MessagesProcesser.this.processMessage((String)o);
}
}.setName("MessagesProcessor").init();
public void gotMessageEvent(String s)
{
_consumer.add(s);
}
private void processMessage(String s)
{
System.out.println(_name+" processed message: "+s);
}
private void terminate()
{
_consumer.terminateWait();
_name = null;
}
MessagesProcessor()
{
_name = "Example Consumer";
}
}
正如您可以從上面的代碼中所看到的,定制 Consumer 相當簡單。我們使用了一個匿名內部類來繼承 Consumer 類,并重載抽象方法 onConsume()。因此,在我們的示例中,只需調用 processMessage。
Consumer 類的高級特性
除了開始時提出的基本需求以外,我們還為 Consumer 類提供了一些我們覺得有用的高級特性。
事件通知
onThreadTerminate():只在終止 Consumer 前調用該方法。我們出于調試目的覆蓋了這個方法。
goingToRest():只在 Consumer 線程進入休眠前調用該方法(也就是說,只在調用 _waitForJobsMonitor.wait() 之前調用)。只在需要消費者在進入休眠之前處理一批已處理工作的復雜情況中,可能需要這種通知。
終止
terminate():Consumer 線程的異步終止。
terminateWait():設置調用線程一直等待,直到消費者線程實際終止為止。
在我們的示例中,如果使用 terminate() 而不是 terminateWait(),那么將會出現問題,因為在將 _name 設置成空值之后調用 onConsume() 方法。這將導致執行 processMessage 的線程拋出一個 NullPointerException。
結束語:Consumer 類的好處
可在參考資料一節下載 Consumer 類的源代碼。請自由使用源代碼,并按照您的需要擴展它。我們發現將這個類用于多線程應用程序開發有許多好處:
代碼重用/重復代碼的消除:如果您有 Consumer 類,就不必為您應用程序中的每個實例編寫一個新的消費者。如果在應用程序開發中頻繁使用生產者-消費者方案,這可以很大程度地節省時間。另外,請牢記重復代碼是滋生錯誤的沃土。它還使基本代碼的維護更為困難。
更少錯誤:使用驗證過的代碼是一種防止錯誤的好實踐,尤其是處理多線程應用程序時。因為 Consumer 類已經被調試過,所以它更安全。消費者還通過在線程和資源之間擔任安全中介來防止與線程相關的錯誤。消費者可以代表其它線程以順序的方式訪問資源。
漂亮、清晰的代碼:使用 Consumer 類有助于我們編寫出更簡單的代碼,這樣的代碼更容易理解和維護。如果我們不使用 Consumer 類,就必須編寫代碼來處理兩種不同的功能:消費邏輯(隊列和線程管理、同步等)和指定消費者的用法或功能的代碼。
看完上述內容,你們對如何使用wait() 和notify() 機制來完成睡眠和踢有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。