2011-03-17 73 views
1

我想知道FileOutputStream.write(byte [])是否總是阻塞當前線程,導致ThreadContext開關,或者如果OS緩衝區足夠大以處理字節,該操作不會阻止。FileOutStream.write(byte [])總是阻塞嗎?

這些想法的原因是,我想知道在我的應用程序中使用log4j進行的日誌記錄是否是真正的性能命中,以及如果使用由單獨的線程讀取的日誌消息隊列以及是否更快寫入日誌文件(我知道吞下日誌語句的缺點,如果應用程序退出並且隊列中的語句未刷新到磁盤)。

不,我沒有介紹它,這些都是相當概念化的想法。

回答

4

您可以使用log4j org.apache.log4j.AsyncAppender並且日誌調用不會阻塞。實際的日誌記錄在另一個線程中完成,因此您不必擔心log4j調用不及時返回。

+0

+1這就是爲什麼我喜歡log4j。一切已經存在...... – Daniel 2011-03-17 09:22:42

5

不需要。

FileOutputStream.write(byte [])是一種本地方法。常識意味着write()可能會寫入內部緩衝區,稍後調用flush()實際上會提交它。

+1

+1指出它確實取決於如何實現write()(這是平臺相關的)。 – sleske 2011-03-17 09:24:38

+2

+1我相信log4j會在每次寫入之後刷新其消息,因此程序會等待消息寫入磁盤。但:總是阻止刷新?操作系統可能會將緩衝區複製到內部緩衝區並立即返回,並將數據異步寫入磁盤。 – Daniel 2011-03-17 09:29:24

+2

@Daniel好想法。但Outputstreams沒有像BufferedOutputStream一樣的緩衝區,所以我認爲調用flush可能實際寫入磁盤,除非你使用BufferedOutputStream的緩衝版本 – 2011-03-17 09:32:43

3

默認情況下immediateFlush已啓用,這意味着日誌記錄速度較慢但確保每個附加請求實際寫出。如果您不關心在應用程序崩潰時是否寫出最後一行,則可以將其設置爲false。

log4j.appender.R.ImmediateFlush=false 

而且,看看這個職位上Log4j: Performance Tips,其中筆者得到了使用immediateFlushbufferedIOasyncAppender一些測試的統計信息。他總結說,對於本地日誌記錄「設置immediateFlush=false,並將bufferedIO保留爲不緩衝的默認值」,並且「asycAppender實際上比正常的非asyc需要更長的時間」。

+1

+1感謝您的鏈接。但文章有一些問題。作者不測量響應時間,只是記錄本身,只要原始請求處理得很快,我不關心它是否延遲了幾毫秒。 – Daniel 2011-03-17 09:31:34

+1

另外,作者沒有使用多線程進行測試,並且單個cpu機器上的AsyncAppender無論如何都沒用。 – Daniel 2011-03-17 09:37:22

1

這很可能取決於操作系統,驅動程序和底層文件系統。如果寫入緩存被啓用,例如它可能會馬上返回。只要IO不是瓶頸,我就看到了同步寫入的千兆/每天日誌,而不會影響性能。如果您擔心響應時間,那麼仍然可能需要異步編寫它們。它消除了潛在的未來問題,例如如果您更改爲寫入網絡驅動器並且網絡出現問題。

+0

+1響應時間是我最關心的問題。我很樂意能夠減少他們,甚至毫秒。 – Daniel 2011-03-17 09:31:17

相關問題