Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.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 什么是';故障导致的线程终止';提到_Java_Multithreading_Executorservice - Fatal编程技术网

Java 什么是';故障导致的线程终止';提到

Java 什么是';故障导致的线程终止';提到,java,multithreading,executorservice,Java,Multithreading,Executorservice,ExecutorService的javadoc有时指线程“由于故障”而终止的情况。然而,不清楚这指的是什么样的失败 例如,文件上说 如果此单个线程在执行过程中由于故障而终止 在关闭之前,如果需要执行,将使用一个新的替换 后续任务 我本以为这种情况可能发生在异常的情况下,或者可能发生RuntimeException,但事实似乎并非如此。运行以下代码似乎给出了相同的线程名称和线程ID ExecutorService executor = Executors.newSingleThreadExecut

ExecutorService
的javadoc有时指线程“由于故障”而终止的情况。然而,不清楚这指的是什么样的失败

例如,文件上说

如果此单个线程在执行过程中由于故障而终止 在关闭之前,如果需要执行,将使用一个新的替换 后续任务

我本以为这种情况可能发生在异常的情况下,或者可能发生
RuntimeException
,但事实似乎并非如此。运行以下代码似乎给出了相同的线程名称和线程ID

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
  System.out.println("Hello from " + Thread.currentThread().getName()+ " " + Thread.currentThread().getId());
  throw new NullPointerException("Test");
});

executor.submit(() -> {
  System.out.println("Hello 2 from " + Thread.currentThread().getName() + " " + Thread.currentThread().getId());
});
此代码的输出为:

Hello from pool-1-thread-1 12
Hello 2 from pool-1-thread-1 12
即使在
NullPointerException
的情况下,似乎也在重用同一个线程


那么Javadoc指的是哪种“失败”?

这是一个有趣的问题。在
ThreadPoolExecutor
中的代码之后,当
Runnable
传递给
execute()
方法时,线程将被丢弃


调用
submit()
时,执行器会为类型为
FutureTask
的可调用/可运行创建一个包装器
FutureTask.run()
具有捕获异常并存储它们的一些逻辑(因此,您可以从
未来的
中查询该异常)。在这种情况下,异常永远不会到达
线程池,因此线程不会被丢弃。

Augusto是正确的
Runnable
任务在
execute()
方法中作为参数传递时,遇到异常后应该丢弃线程

我已经找到了具体的证据,证明在这个和这个阶段,未来的任务会接受异常

在SE中,围绕这一主题还有一些更有趣的问题

编辑:

当线程代码中没有异常时,将发生线程失败或终止。如果您通过
execute()
而不是
submit()
提交任务,则除非捕获异常,否则不会捕获异常。线程代码的未捕获异常将导致线程终止或失败,执行器将创建新线程


如果您通过
submit()”提交任务,则将创建
FutureTask
,该任务将吞噬代码未捕获的异常。由于异常是在
FutureTask
中捕获的,因此线程不会被丢弃。

这与其说是知识,不如说是猜测,但
failure
对我来说意味着与软件无关的东西。可能是硬件故障?嗯。。。硬件相关故障听起来太严重了。。。在这种情况下,为什么它会启动另一个线程,好像什么都没发生?我想与操作系统相关的线程终止可能是一个更合理的情况。谢谢你的回复。我仍然不清楚他们所说的“失败”是什么,它会导致一个线程被丢弃,一个新线程启动。您所指示的代码清楚地显示线程状态已检查。我更感兴趣的是,是什么导致了线程死亡(如果不是异常的话,那么无论如何都会被捕获)。异常是为将来而存在的,但不是为Runnable提交的,它使用execute()而不是submit()。如果遇到未捕获异常并导致线程被丢弃,它们将死亡。将代码更改为execute()并检查线程IdSo什么将导致线程“失败”,executerservice将检测其失败并生成新线程?由于包装器的原因,在调用
submit()
时不会发生这种情况。如果调用
execute()
,线程抛出异常,线程执行器将生成一个新线程。要测试这一点,请获取代码并将
submit()
替换为
execute()
,您将看到执行器创建了一个新线程。
**Inside FutureTask$Sync**

void innerRun() {
        if (!compareAndSetState(READY, RUNNING))
            return;

      runner = Thread.currentThread();
        if (getState() == RUNNING) { // recheck after setting thread
            V result;
           try {
                result = callable.call();
            } catch (Throwable ex) {
               setException(ex);
                return;
            }
           set(result);
        } else {
            releaseShared(0); // cancel
        }
   }


   protected void setException(Throwable t) {
       sync.innerSetException(t);
   }