2011-10-13 33 views
3

我想添加異步輸出到我的程序。在Java中使用多線程時,常規隊列是否不適合使用?

目前,我有一個eventManager類,獲取每個幀的當前存在於主循環中的任何可移動對象的位置(它渲染一個場景;一些對象隨幀變化,其他對象是靜態的並存在在每一幀)。我正在尋找記錄每個幀的狀態,以便我可以添加功能來重放場景。

這意味着我需要在不同幀之間存儲不斷變化的信息,並將其保存在內存中或將其寫入磁盤供以後檢索和解析。我已經做了一些時間實驗,將每個對象的狀態記錄到內存中,每幀的時間增加了約25%(更不用說最終達到內存限制的可能性)。直接將每個幀寫入磁盤需要(可預測)甚至更長,接近兩倍於根本不記錄幀。

不用說,我想實現多線程,這樣我就不會在我的主渲染循環中丟失幀數,因爲這個過程一直在寫入磁盤。

我不知道它是否是好使用常規隊列此任務,或者如果我需要更多的東西專用像this question討論的隊列。

在我的情況下,只有一個生產者(主線程)和一個消費者(我想要異步寫入磁盤的線程)。生產者永遠不會從隊列中移除,而且消費者永遠不會加入 - 所以我需要一個專門的隊列嗎?

反正使用更專門的隊列有沒有優勢

回答

4

是的,一個正規的Queue是不適合的。既然你有兩個線程,你需要擔心邊界條件,比如空隊列,完整隊列(假設你需要爲了內存考慮而限制它)或異常情況等。

A LinkedBlockingQueue最適合您的應用。 puttake方法使用不同的鎖,因此您不會發生鎖爭用。 take方法將自動阻止消費者寫入磁盤,如果它奇蹟般地趕上生產者渲染幀。

2

我認爲這不重要。

如果你有25%的開銷在內存中序列化一個狀態,那將仍然在隊列中。 磁盤將更加昂貴。 與之相比,隊列阻塞機制便宜。

有一點需要注意的是你的隊列不受控制:無論如何,如果隊列事件不能足夠快地消耗隊列事件,你就會陷入麻煩。

3

聽起來好像你不需要一個特殊的隊列,但是如果你希望線程從隊列中刪除,直到有什麼東西可以得到,請嘗試BlockingQueue。它在java.util.concurrent包中,所以確實是線程安全的。下面是從該網頁的一些相關報價:

支持兩個附加存儲時等待隊列 檢索元素時,成爲非空,等待空間 隊列變得可用操作的Queue一個元素。

...

BlockingQueue實現被設計爲主要用於 生產者 - 消費者隊列,但它另外還支持Collection 接口。

...

BlockingQueue實現是線程安全的。

只要你已經剖析你的代碼,試圖在那裏丟棄BlockingQueue看看會發生什麼!

祝你好運!

+0

啊是的,每@Tim,LinkedBlockingQueue是唯一的。 'BlockingQueue'是'LinkedBlockingQueue'實現的接口。 – andronikus

相關問題