我想知道FileOutputStream.write(byte [])是否总是阻塞当前线程,导致ThreadContext开关,或者可能是如果操作系统缓冲区很大,则该操作不会阻塞,以便处理字节。 / p>
这些想法的原因是,我想知道我在我的应用程序中使用log4j进行的日志记录是否真的是性能损失,并且如果使用由单独的线程读取并记录的日志消息队列会更快到日志文件(如果应用程序退出并且队列中的语句没有刷新到磁盘,我知道swallowed logging语句的缺点。)
不,我还没有描述它,这些是相当概念性的想法。
答案 0 :(得分:5)
不必是。
FileOutputStream.write(byte [])是一种本机方法。常识会建议write()可以只写入内部缓冲区,稍后调用flush()实际上会提交它。
答案 1 :(得分:4)
您可以使用log4j org.apache.log4j.AsyncAppender
,并且日志记录调用不会阻止。实际的日志记录是在另一个线程中完成的,所以你不必担心调用log4j不能及时返回。
答案 2 :(得分:3)
默认情况下启用immediateFlush
,这意味着日志记录速度较慢但确保实际写出每个追加请求。如果您不关心在应用程序崩溃时是否写出最后一行,则可以将其设置为false。
log4j.appender.R.ImmediateFlush=false
另外,请查看Log4j: Performance Tips上的这篇文章,其中作者获得了有关使用immediateFlush
,bufferedIO
和asyncAppender
的一些测试统计信息。他的结论是,对于本地日志记录“设置immediateFlush=false
,并将bufferedIO
保留为默认值”不缓冲“,并且”asycAppender
实际上需要比正常非asyc更长的时间“。< / p>
答案 3 :(得分:1)
这可能取决于操作系统,驱动程序和底层文件系统。如果启用了写缓存,例如它可能会立即返回。我已经看到同步写入千兆字节/天的日志而不会影响性能太多,只要IO没有瓶颈。如果你担心响应时间,那么仍然可能值得异步编写它们。它消除了潜在的未来问题,例如如果您更改为写入网络驱动器并且网络出现问题。