控制台输出是阻塞操作吗?

use*_*215 8 java multithreading scala nonblocking blocking

当Java程序调用System.out.println()或Scala程序调用println()时,线程是否阻塞?

我正在编写一个带有大量子任务的Scala程序.每个子任务都在Future中执行.建议actor和future内的代码不会阻塞,以便后续任务也不必等待.但我想在控制台上打印很多.

如果是阻塞操作:我可以做些什么来优化性能?

  • 我应该使用专用线程进行控制台输出,以便线程是唯一阻塞的线程吗?
  • 还有其他任何建议吗?

当然,我可以尝试减少输出量或收集StringBuilder中的一些输出并将它们一起打印,这样可以减少输出操作的数量.

Gra*_*ray 14

当Java程序调用System.out.println()或Scala程序调用println()时,线程是否阻塞?

是的,不是. System.out是一个PrintStream同步类.因此,写入大量数据的多个线程System.out肯定会相互阻塞.然而,一旦线程获得锁定,IO是否将阻止线程取决于体系结构.如果你写了大量的IO来压倒底层硬件的容量,那么写阻塞.此外,进行大量小写操作(与缓冲相反)也会减慢线程速度.

我应该使用专用线程进行控制台输出,以便线程是唯一阻塞的线程吗?

好主意,是的.然后这个线程可以通过单个BufferedWriter或某种类型的log4j或其他日志包来编写,与之相比,这将是更高效的System.out.您将需要使用类似a的东西BlockingQueue来排队同步的消息,但IO永远不会阻止此队列,除非您生成的消息比IO通道可以持久保存的速度快.

当然,我可以尝试减少输出量或收集StringBuilder中的一些输出并将它们一起打印,这样可以减少输出操作的数量.

BufferedWriter会照顾这个要求.

还有其他任何建议吗?

  • 如上所述,使用更好的日志包或单线程编写器.
  • 将日志写入具有更多IO带宽的其他物理磁盘.
  • 切换到内存文件系统或硬件以增加IO带宽.SSD ++.
  • 通过网络将其发送到另一个框以执行实际的持久关闭框.
  • 使用a GzipOutputStream来动态压缩它.


dar*_*jan 5

这要看情况。在Windows OS上,这是一项阻止操作,并且涉及很多内核内容才能将某些内容打印到控制台。在类似UNIX的OS中,操作被缓冲,因此不会被认为是缓慢的。

我建议您使用缓冲区方法,并且有一个单独的线程也是一个好主意。或者,如果您的输出不那么重要,则可以将其写入文件,这比写入控制台要快得多。