这个Java未捕获错误的原因可能是什么?

3

我有一个多线程的Java程序。主线程在第二个线程中执行以下代码,随后第二个线程结束。

try{
   System.out.println(1); //prints
   doSomething();
   System.out.println(2); //doesn't print
} catch(Throwable t) {
   System.out.println(3); //doesn't print
}

我运行这段代码时,偶尔会在控制台看到数字 1 输出,而数字 2 或者 3 没有出现。因此,似乎 doSomething 方法抛出了某种错误导致线程停止。这种情况大约发生在 0.5% 的时间里。由于没有 Throwable 导致线程终止,可能会发生什么问题呢?
主线程在第二个线程停止后仍然可以正常继续运行。
以下是我用于创建和运行第二个线程的代码。
Runnable secondThread = new Runnable() { ... }
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
threadPoolExecutor.execute(secondThread);


编辑: doSomething 是对外部网站REST API的调用。

请展示你正在使用的用于等待第二个线程的代码。 - PiRocks
@PiRocks 嗯,即使第二个线程已经完成,主线程仍然运行了很多分钟。在记录“1”之后,我看到许多来自主线程的日志消息。doSomething只需要大约1秒钟的时间。 - JacksonCounty
1
假定 doSomething 正在阻塞或者需要异常长的时间才能完成。如果这个方法正常完成或者抛出异常,无法避免打印 2 或者 3。 - Michael
@Michael 没有其他的错误类型吗?比如 AssertionError 或者其他突然终止线程的方式? - JacksonCounty
1
没有。 - Michael
显示剩余13条评论
2个回答

2
听起来像是doSomething函数没有结束。由于您调用了外部服务,可能会导致它挂起。请按照以下步骤操作: 调用jps命令。 该命令位于java所在的同一目录中。 它将列出所有Java进程的列表。 然后调用jstack命令加上进程id即可。

-1

你问题的唯一答案是在你第一次输出和第二次输出之间,另一个线程正在向System.out打印。

为了解决这个问题,你应该使用锁。

static Object lock = ...; //everyone who's printing to System.out should synchronize on this before printing to System.out

synchronized (lock) {
  try{
     System.out.println(1); //prints
     doSomething();
     System.out.println(2); //doesn't print
  } catch(Throwable t) {
     System.out.println(3); //doesn't print
  }
}

1
不知道你是怎么得出那个结论的。在这种情况下,2或3最终会被打印出来,只是可能顺序与预期不同。他说它们根本没有被打印出来。 - Michael
@ControlAltDel 问题不在于另一个线程在 12 中打印,而是 23 没有打印,这是一个不同的问题。 - JacksonCounty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接