【问题标题】:Is console output a blocking operation?控制台输出是阻塞操作吗?
【发布时间】:2013-06-22 15:27:54
【问题描述】:

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

我正在编写一个包含大量子任务的 Scala 程序。每个子任务都在 Future 中执行。建议actors和futures内部的代码不要阻塞,这样后续的任务也不必等待。但我非常想在控制台上打印。

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

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

当然我可以尝试减少输出量,或者在StringBuilder中收集一些输出,然后批量打印出来,这样可以减少输出操作的次数。

【问题讨论】:

    标签: java multithreading scala blocking nonblocking


    【解决方案1】:

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

    是和不是。 System.out 是一个 PrintStream,它是一个同步类。因此,向System.out 写入大量数据的多个线程肯定会相互阻塞。然而,一旦线程获得锁,IO 是否会阻塞线程取决于架构。如果您写入的大量 IO 超出了底层硬件的容量,那么写入 阻塞。此外,进行大量小写入(而不是缓冲写入)也会减慢线程速度。

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

    好主意,是的。然后这个线程可以通过单个BufferedWriter 或某种log4j 或其他日志包写入,与System.out 相比,它们的性能要高得多。您将需要使用BlockingQueue 之类的东西来排队同步消息,但 IO 永远不会阻塞此队列,除非您生成消息的速度快于 IO 通道可以持久的速度。

    当然我可以尝试减少输出量,或者在StringBuilder中收集一些输出,然后批量打印出来,这样可以减少输出操作的次数。

    BufferedWriter 会为您解决这个问题。

    还有什么建议吗?

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

    【讨论】:

    • 将日志写入不同的文件系统。您的意思是不同的物理驱动器?或者,如果您的意思是一种文件系统比另一种更适合此类任务(例如 ext* 与 btrfs),您能否透露名称?
    • 不,我的意思是 IO 链,而不是不同的 FS 类型 @om-nom-nom。顺便说一句,很棒的用户名。 :-)
    • 我从未听说过 System.out 是“非阻塞的”。它不是在 java.nio 之上实现的,是吗?如果您使用重定向到慢速设备上的文件的 stdout 运行,我很确定对 System.out.println() 的任何调用都会阻塞并且在写入完成之前不会返回。另外,我认为这与 printwriter 作为同步类没有任何关系。您可以轻松地创建一个执行阻塞 IO 的 java 方法,而无需标记类或方法“同步”。在最低级别,有一个 C 或内核调用 write() 直到完成才会返回,阻塞线程直到它返回。
    • 这取决于@faffaffaff 的架构。所有的 IO 操作在某种程度上都是阻塞的。我试图解释的是,在您填充您正在写入的设备的 IO 流之前(至少在 Unix 下),写入不会阻塞线程。它只会被复制到内核缓冲区中。我已经调整了答案。
    • 从软件的角度来看确实如此,但有关线程是否要停止并等待 IO 完成的实际细节更复杂@faffaffaff。 OP 正在询问多线程日志记录的性能。这更多是关于操作系统如何处理写操作的现实,然后是“阻塞”的定义。
    【解决方案2】:

    视情况而定。在 Windows 操作系统上,它是一个阻塞操作,涉及到很多内核内容来将某些内容打印到控制台。在类似 UNIX 的操作系统中,操作是缓冲的,因此不会被认为很慢。

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

    【讨论】:

    • 还要记住 System.out 不一定会打印到控制台(它可能已被重定向到带有“command > out.txt”的文件)
    猜你喜欢
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    相关资源
    最近更新 更多