当Java程序调用System.out.println()或Scala程序调用println()时,线程阻塞吗?
我正在编写一个包含大量子任务的Scala程序。每个子任务都在Future中执行。建议actor和future内的代码不会阻塞,以便后续任务也不必等待。但我想在控制台上打印很多。
如果是阻止操作:我可以做些什么来优化性能?
当然,我可以尝试减少输出量或在StringBuilder中收集一些输出并一起打印,这样可以减少输出操作的数量。
答案 0 :(得分:13)
当Java程序调用System.out.println()或Scala程序调用println()时,线程阻塞吗?
是和否。 System.out
是PrintStream
,是同步类。因此,将大量写入System.out
的多个线程肯定会相互阻塞。然而,一旦线程获得锁定,IO是否将阻止线程取决于体系结构。如果您编写的大量IO超出底层硬件的容量,那么写将阻塞。此外,制作大量小写(与缓冲相反)也会使线程变慢。
我是否应该使用专用线程进行控制台输出,以便线程是唯一可以阻塞的线程?
很棒的主意,是的。然后,这个线程可以通过单个BufferedWriter
或某种log4j或其他日志包来编写,与System.out
相比,它会更高效。您将需要使用BlockingQueue
之类的内容来排队同步的消息,但IO永远不会阻止此队列,除非您生成的消息比IO通道可以持续生成的消息更快。
当然,我可以尝试减少输出量或在StringBuilder中收集一些输出并一起打印,这样可以减少输出操作的数量。
BufferedWriter
将为您解决此问题。
还有其他任何建议吗?
GzipOutputStream
动态压缩它。答案 1 :(得分:4)
取决于。在 Windows 操作系统上,它是一个阻塞操作,涉及很多内核,可以将某些东西打印到控制台。在 UNIX -like OS中,操作被缓冲,因此不会感觉很慢。
我建议你使用缓冲区方法,并且有一个单独的线程也是一个好主意。或者如果您的输出不那么重要,您可以将其写入文件,这比写入控制台要快得多。