【问题标题】:What could be causing this Java uncaught error什么可能导致此 Java 未捕获错误
【发布时间】:2020-05-02 11:38:08
【问题描述】:

我有一个多线程 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 的调用。

【问题讨论】:

  • 您是否在第二个线程有机会运行之前终止了 Jvm?
  • 请向我们展示您用于等待第二个线程的代码。
  • @PiRocks 在第二个线程完成后,主线程会继续运行几分钟。在 1 被记录后,我从主线程中看到了许多日志消息。 doSomething 只需要大约 1 秒。
  • 可能doSomething 正在阻塞或以其他方式花费异常长时间才能完成。如果此方法正常完成或抛出异常,则无法避免打印 2 或 3。
  • 不,没有。

标签: java multithreading exception error-handling throwable


【解决方案1】:

听起来 doSomething 不会终止。由于您调用外部服务,它可能会挂起。请执行下列操作: 致电jps 它位于 java 所在的同一目录中。 它为您提供了所有 java 进程的列表。 然后调用jstack进程id

【讨论】:

    【解决方案2】:

    您的问题的唯一答案是在您的第一个打印输出和第二个打印输出之间,另一个线程正在打印到 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
      }
    }
    

    【讨论】:

    • 不知道你是怎么得出这个结论的。在这种情况下,最终会打印 2 或 3 个 ,只是顺序可能与预期不同。他是说它们根本没有打印出来。
    • @ControlAltDel 问题不在于另一个线程在1 和2 内打印,而是2 和3 从不打印,这是一个不同的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2011-01-07
    • 1970-01-01
    • 2023-03-24
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多