Java並行開發筆記6

2021-09-01 22:41:56 字數 1863 閱讀 8088

對於持有執行緒的服務,只要服務的存在時間大於建立執行緒的方法的存在時間,那麼就應該提供生命週期方法。

在下面的程式中給出了乙個簡單的日誌服務示例,其中日誌操作在單獨的日誌執行緒中執行。產生日誌訊息的執行緒並不會將訊息直接寫入輸出流,而是由logwriter通過blockingqueue將訊息提交給日誌執行緒,並由日誌執行緒寫入。這是一種多生產者單消費者(multiple-producer,single-consumer)的設計方式:每個呼叫log的操作都相當於乙個生產者,而後台的日誌執行緒則相當於消費者。如果消費者的處理速度低於生產者的生成速度,那麼blockingqueue將阻塞生產者,直到日誌執行緒有能力處理新的日誌訊息。

不支援關閉的生產者-消費者日誌服務

public class logwriter 

public void start()

public void log(string msg) throws interruptedexception

private class loggerthread extends thread

public void run()

}catch(interruptedexception innored)finally

} }}

一般地,像logwriter這樣的服務在軟體產品中能發揮實際的作用,還需要實現一種終止日誌執行緒的方法,從而避免使jvm無法正常關閉。

一種關閉logwriter的方法是:設定某個「已請求關閉」標誌,以避免進一步提交日誌訊息。但存在競態問題,提供可靠關閉操作能夠解決該問題,因而要使日誌訊息的提交操作成為原子操作。具體**如下:

public class logservice 		

public void start()

public void stop()

loggerthread.interrupt(); }

public void log(string msg) throws interruptedexception

++reservations;

} queue.put(msg); }

private class loggerthread extends thread

}string msg = queue.take();

synchronized(logservice.this)

writer.println(msg);

}catch(interruptedexception e)

}}finally

} }}

另外一種關閉生產者-消費者服務的方式就是使用「毒丸(poison pill)」物件:「毒丸」是指乙個放在佇列上的物件,其含義是:「當得到這個物件時,立即停止」。 示例**如下:

public class indexingservice 

public void stop()

public void awaittermination() throws interruptedexception

public class crawlerthread extends threadcatch(interruptedexception e)finallycatch(interruptedexception e1)}}

} private void crawl(file root) throws interruptedexception

} public class indexerthread extends threadelse

}}catch(interruptedexception consumed)

} private void indexfile(file file)

} }

Java並行開發筆記1

加鎖機制既可以確保可見性又可以確保原子性,而volatile變數只能確保可見性。當前僅當滿足一下所有條件時,才應該使用volatile變數 執行緒封閉 當訪問共享的可變資料時,通常需要使用同步。一種避免使用同步的方式就是不共享資料。如果僅在單執行緒內訪問資料,就不需要同步。這種技術被稱為執行緒封閉 ...

golang開發筆記No 6

關於channel,下面語法正確的是 下面這段 輸出什麼?package main import fmt type person struct func main fmt.println m p 參 及解析 0,列印乙個 map 中不存在的值時,返回元素型別的零值。這個例子中,m 的型別是 map ...

IOS開發筆記6 迴圈結構 下篇

do while語法 int main while 表示式 return 0 do while執行順序 當遇到do while迴圈結構時,首先執行一次迴圈體中的語句,接著判斷表示式成立與否,如果成立就執行迴圈體中的語句。然後再次判斷表示式,重複上述過程,直到表示式不成立則結束迴圈。特點 無論表示式成...