2016-11-18 124 views
0

我正在编写一个使用log4j进行日志记录的Java多线程应用程序。在我的基准测试期间,我发现每次输出日志时都会产生1或2毫秒的延迟。调查后,我发现问题只出现在控制台输出中,即使我摆脱了log4j并直接使用System.out.print打印,也发生了这种问题。在该线程,我用了以下测试:Java多线程应用程序System.out.println生成延迟

 System.out.println("==============================================================="); 
     long ts = java.lang.System.currentTimeMillis(); 
     String toPrint = "### TEST 1 " + (java.lang.System.currentTimeMillis() - ts) + " ms \n"; 
     toPrint = toPrint + "### TEST 2 " + (java.lang.System.currentTimeMillis() - ts) + " ms \n"; 
     toPrint = toPrint + "### TEST 3 " + (java.lang.System.currentTimeMillis() - ts) + " ms \n"; 
     toPrint = toPrint + "### TEST 4 " + (java.lang.System.currentTimeMillis() - ts) + " ms \n"; 
     System.out.print(toPrint); 
     System.out.println("==============================================================="); 

     System.out.println("### TEST 1 " + (java.lang.System.currentTimeMillis() - ts) + " ms"); 
     System.out.println("### TEST 2 " + (java.lang.System.currentTimeMillis() - ts) + " ms"); 
     System.out.println("### TEST 3 " + (java.lang.System.currentTimeMillis() - ts) + " ms"); 
     System.out.println("### TEST 4 " + (java.lang.System.currentTimeMillis() - ts) + " ms"); 
     System.out.println("==============================================================="); 

,输出是:

=============================================================== 
### TEST 1 0 ms 
### TEST 2 0 ms 
### TEST 3 0 ms 
### TEST 4 0 ms 
=============================================================== 
### TEST 1 7 ms 
### TEST 2 9 ms 
### TEST 3 10 ms 
### TEST 4 11 ms 
=============================================================== 

什么是正确的方法为多线程应用程序直接输出到控制台,而无需创建延迟?

我们可以设置log4j来直接做到这一点吗?

预先感谢你的帮助......

+1

在这种延迟是一个问题 - 每一项工作需要一些时间 - 然后可能创建一个新的线程,只是你的打印。 –

+0

写入控制台需要一点时间。就是那样子。如果您记录了很多事情来控制它,请减少日志级别,或完全关闭控制台日志记录。你总是可以“尾巴”你可能产生的日志文件。 – Andreas

+0

@Andreas非常感谢您的回答。然而,我的CPU没有饱和,并且在现代服务器上输出一行2毫秒听起来不合理。关闭控制台确实修复了pb。 – deubNippon

回答

1

我不得不改变代码的Nano看到的结果。在Eclipse中运行我获得最终编号~120,000 ns。在Windows命令提示符下运行我在清除提示时(在cls命令之后)获取~700,000 ns,但在需要滚动时获得~2,000,000 ns

写入控制台是同步,并且必须等待滚动和打印才能完成,因此不要登录到控制台,或者只记录非常小的输出。

您在评论中说您正在登录文件控制台。在开发,但没有在生产登录到控制台。你为什么?无论如何,生产代码应该无人值守运行,并且没有人正在监视控制台,那么为什么要浪费时间登录?

如果您暂时需要实时查看生产日志,请在日志文件上使用tail。对于Windows,请参阅“Looking for a windows equivalent of the unix tail command”。

如果您坚持登录到控制台,请尝试使用AsyncAppender

+0

Thx很多,我没有意识到控制台io是如此昂贵。你确实回答我的第一个问题。然而,log4j 2应该解决这些问题,任何想法如何确保控制台io可以在低优先级的单独线程中使用log4j来完成? (现在我按照你的建议去做,并关闭控制台输出) – deubNippon