是什么导致了这个 Java 未捕获的错误
What could be causing this Java uncaught error
我有一个多线程 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 的调用。
您问题的唯一答案是,在您的第一个打印输出和第二个打印输出之间,另一个线程正在打印到 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
}
}
听起来 doSomething 没有终止。由于您调用外部服务,它可能会挂起。请执行下列操作:
打电话 jps
它位于 java 所在的同一目录中。
它为您提供了所有 java 个进程的列表。
然后调用jstack进程id
我有一个多线程 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 的调用。
您问题的唯一答案是,在您的第一个打印输出和第二个打印输出之间,另一个线程正在打印到 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
}
}
听起来 doSomething 没有终止。由于您调用外部服务,它可能会挂起。请执行下列操作: 打电话 jps 它位于 java 所在的同一目录中。 它为您提供了所有 java 个进程的列表。 然后调用jstack进程id