What does “thread termination due to failure” mean?

javadoc for ExecutorService sometimes refers to the case where Thread terminates "due to a failure." However, it is not clear to which failure this applies.

For example, the single thread executor documentation states that

if this single thread terminates due to a run-time failure before shutting down, a new one will take its place if necessary to complete subsequent tasks

I would think that such a situation could happen in the event of an exception or maybe a RuntimeException , but it does not seem to be so. Executing the following code seems to give the same stream name and stream identifier.

 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()); }); 

The output of this code is:

 Hello from pool-1-thread-1 12 Hello 2 from pool-1-thread-1 12 

It seems that the same thread is reused even in the case of a NullPointerException .

So what is the “failure” for Javadoc?

+5
source share
2 answers

This is an interesting question. After the code in ThreadPoolExecutor thread is discarded when the Runnable is passed to the execute() method.

When submit() called, the executor creates a wrapper for the called / executed type of FutureTask . FutureTask.run() has some logic to catch exceptions and store them (so you can request this from Future ). In this case, the exception never reaches ThreadPool , so the thread is not discarded.

+2
source

Augusto is right. Runnable tasks should throw Thread after detecting an exception when they are passed as a parameter in the execute() method.

I found concrete evidence regarding swallowing exceptions for future tasks in this article and the Source code for a future task

 **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); } 

SE has some interesting questions on this topic.

Fix thread exceptions from Java ExecutorService

Choose between the ExecutorService view and the ExecutorService view

EDIT:

A malfunction or termination of the stream will occur if an exception is not shown in the stream code. If you submit an execute() job instead of submit() , the exception will not be detected unless you catch the exception. Excluding the exception from the stream code will result in the termination or failure of the stream, and Executor will create a new stream.

If you submit the task via submit(), FutureTask will be created, and this task will swallow the uncaught exception with code. Since the exception fell into FutureTask , the thread will not be discarded.

0
source

Source: https://habr.com/ru/post/1236008/


All Articles