Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,System.err.println在线程压力下失败_Java_Multithreading_Thread Safety - Fatal编程技术网

在Java中,System.err.println在线程压力下失败

在Java中,System.err.println在线程压力下失败,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我正在用java编写一个程序,其中我使用一些错误打印语句进行调试。 我的程序生成大约2000个线程。程序运行良好,直到大量线程访问此语句: System.err.println("Some error message"); 发生这种情况时,我的一个线程成功地访问了println函数,而其他线程的状态为: JVM中的状态:等待同步块 在调试语句中深入挖掘,我注意到试图访问println函数的线程在该函数处停止: private native void writeBytes(b

我正在用java编写一个程序,其中我使用一些错误打印语句进行调试。 我的程序生成大约2000个线程。程序运行良好,直到大量线程访问此语句:

System.err.println("Some error message");
发生这种情况时,我的一个线程成功地访问了println函数,而其他线程的状态为:

JVM中的状态:等待同步块

在调试语句中深入挖掘,我注意到试图访问println函数的线程在该函数处停止:

private native void writeBytes(byte b[], int off, int len , boolean append) throws IOException;
并且它具有以下堆栈跟踪:

java.io.FileOutputStream.write(FileOutputStream.java:327)

flushBuffer(BufferedOutputStream.java:82)

java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)

java.io.PrintStream.write(PrintStream.java:482)

writeBytes(StreamEncoder.java:221)

sun.nio.cs.streamncoder.implFlushBuffer(streamncoder.java:291)

flushBuffer(StreamEncoder.java:104)

java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)

java.io.PrintStream.write(PrintStream.java:527)

PrintStream.print(PrintStream.java:669)

println(PrintStream.java:806)

fetcher.responseHandler.ExtendedResponseHandler500.HandlerResponse(ExtendedResponseHandler500.java:20)

fetcher.FetchWorker.run(FetchWorker.java:79)

run(Thread.java:745)

当其他线程停止在println函数的第一行时(在java核心代码中):


这个问题是由我引起的吗?或者这个错误与JVM有关?我能对此问题做些什么吗?

对于2000个线程来说,等待获取println调用的锁是完全正常的

堆栈跟踪显示您收到一些HTTP 500错误。您的大多数线程可能都出现了此错误,现在都在排队报告标准错误。你所看到的是你问题的结果,而不是原因

2000个线程是一个疯狂的数字,它不会在任何合理的情况下提高性能,而且很可能会降低性能。从4开始,看看增加一倍该值是否能带来任何改善。JVM可以处理这个数量的线程(因此这不是问题的根源),但它毫无用处。使用更多的JVM并不能解决问题(这可能是一个简单的HTTP 500和/或网络超时)。 还要检查服务器端日志

如果您需要最大化性能(在真正的高并发场景中)考虑AssiCHIO,但正常IO对于所有常见情况都非常好,在这里似乎很好。 更新: 我的想法是:

  • 线程执行远程调用
  • 它有500个错误
  • 它加入该行以报告其他2000个线程后面的错误
  • 它成功了,回到了第1点
  • 步骤3可能需要很多时间,因此即使进行多个线程转储,您也会看到相同的线程始终处于锁定状态(我的意思是,在步骤1或步骤2中,您需要非常幸运地看到线程1352)。我假设您检查了线程名称,并且我们正在讨论的锁定线程总是相同的。
    当程序“冻结”(是否冻结,对吗?)或所有内容都处于静止状态时,您是否看到任何日志?您进行了多少次线程转储,间隔多长时间?

    最可能的原因是父进程没有使用进程的输出流,因此标准输出缓冲区已满,然后下一次调用System.err.println将永远挂起

    当一个进程用于启动另一个进程,但没有设置“刷新”线程来排出子进程的stdout和stderr流时,这种情况很常见


    请注意,这与“线程化”没有任何特殊关系,但启动多个线程肯定会增加错误生成的速率(如果其他线程由于下游争用而失败,则可能会导致更多的总错误)这意味着您的输出缓冲区填充得更快,挂起得更早。

    能否显示一些代码和/或堆栈跟踪?让我们备份一下。。。为什么你的应用程序需要2000个线程?@ JoC它运行在一个服务器上,而不是在我的本地PC上。这些线程的任务是从因特网上获取页面,并且我需要充分利用我的Internet连接带宽。我建议你考虑把这2000个线程划分成多个(几十个,如果不是几百个)的JVM。code>System.err不是设计为能够同时处理那么多线程的。@JoeC谢谢,我会尝试修改我线程的层次结构。首先,
    ExtendedResponseHandler500
    是我创建的一个类,当它遇到问题时,应该报告它。我的问题不是HTTP 500错误,我的问题是当大量线程都在排队报告标准错误时,其中一个线程设法访问println函数,而其他线程则在等待访问。主要问题是这一个线程挂起,它没有完成system.err的使用,导致其他线程永远被阻塞。我看不出有什么明显的原因让您调用java.io.PrintStream的write方法永远被阻塞。一种可能性是,您在其他地方添加了一个“synchronized(System.err)”,用于在不同的上下文中获取System.err监视器。线程冻结时,您是否看到任何活动?还是一切都还在?我已经更新了我的答案。事实上它完全按照我说的那样,只是永远冻结(我试着等了好几个小时,什么也没发生)。此外,我在代码的任何部分都没有使用“synchronized(System.err)”。我知道预期的行为正如你在更新中提到的,但它不是那样发生的,这是我问题的实际原因
    synchronized(this)