The javadoc for ExecutorService sometimes refers to the case when a Thread terminates 'due to failure'. However, it is not clear what kind of failure does this refer to.
For instance, the single thread executor documentation says that
if this single thread terminates due to a failure during execution
prior to shutdown, a new one will take its place if needed to execute
subsequent tasks
I would have thought that this situation might happen in case of an Exception, or maybe a RuntimeException, but it does not seem to be the case. Running the following code seems to be giving the same thread name and thread 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());
});
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 being reused even in the case of NullPointerException.
So what kind of 'failure' is the Javadoc referring to?
This is an interesting question. Following the code in ThreadPoolExecutor the thread is discarded when a Runnable is passed to the execute() method.
When you call submit() the executor creates a wrapper for the callable/runnable of type FutureTask. FutureTask.run() has some logic to catch exceptions and store them (so then, you can query this from the Future). In this case, the exception never reaches the ThreadPool, so the thread is not discarded.
Augusto is right. Runnable tasks should have discarded the Thread after encountering the exception when they have passed as parameter in execute() method.
I have found concrete evidence regarding swallowing of exceptions by Future tasks at this article and Future Task source code
**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);
}
There are few more interesting questions in SE around this topic.
Catching thread exceptions from Java ExecutorService
Choose between ExecutorService's submit and ExecutorService's execute
EDIT:
Thread failure or termination will happen when an exception is uncaught in the thread code. If you submit task by execute() instead of submit(), exception won't be caught unless you catch the exception. Uncaught exception by the thread code will result thread to terminate or failure and new thread will be created by Executor.
If you submit the task through submit(), a FutureTask will be created and that task will swallow uncaught exception by the code. Since the exception was caught in FutureTask, the thread won't be discarded.
Related
How does Executor.newSingleThreadExecutor() behave if I am frequently scheduling tasks to run that are being cancelled with future.cancel(true);?
Does the single thread spawned by the executor get interrupted (so the future code needs to clear the interrupt), or does the interrupt flag get automatically cleared when the next future starts up.
Does the Executor need to spawn an additional thread on every interrupt to be used by the remaining task queue?
Is there a better way?
Good question, I don't find this documented anywhere, so I would say it is implementation dependent.
For example OpenJDK does reset the interrupted flag before every executed task:
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
Snippet from from OpenJDK jdk8u ThreadPoolExecutor#runWorker source.
The following sample program demonstrates that the interrupt is called on the thread if you call the cancel method with true. You can even see that it is reusing the same thread. The cancel returns a boolean which indicates if the cancellation was successful. The javadoc of this method is also clear enough.
class Task implements Callable<String> {
#Override
public String call() throws Exception {
try {
System.out.println("Thread name = " + Thread.currentThread().getName());
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
System.out.println("Interrupted");
return "Interruped";
}
return "X";
}
}
public class Testy {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService =
Executors.newSingleThreadExecutor();
int count = 0;
while (true) {
System.out.println("Iteration " + count++);
Future<String> submit = executorService.submit(new Task());
Thread.sleep(500);
submit.cancel(true);
}
}
}
Output looks like below
Iteration 0
Thread name = pool-1-thread-1
Iteration 1
Interrupted
Thread name = pool-1-thread-1
Iteration 2
Interrupted
Why invoke the method Thread.currentThread.interrupt() in the catch block?
This is done to keep state.
When you catch the InterruptedException and swallow it, you essentially prevent any higher-level methods/thread groups from noticing the interrupt. Which may cause problems.
By calling Thread.currentThread().interrupt(), you set the interrupt flag of the thread, so higher-level interrupt handlers will notice it and can handle it appropriately.
Java Concurrency in Practice discusses this in more detail in Chapter 7.1.3: Responding to Interruption. Its rule is:
Only code that implements a thread's interruption policy may swallow an interruption request. General-purpose task and library code should never swallow interruption requests.
I think this code sample makes things a bit clear.
The class which does the job :
public class InterruptedSleepingRunner implements Runnable {
#Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
// You are kidding me
System.out.println(i + " " + i * 2);
// Let me sleep <evil grin>
if (Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
} else {
sleepBabySleep();
}
}
}
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The Main class:
public class InterruptedSleepingThreadMain {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new InterruptedSleepingRunner());
thread.start();
// Giving 10 seconds to finish the job.
Thread.sleep(10000);
// Let me interrupt
thread.interrupt();
}
}
Try calling interrupt without setting the status back.
Note:
http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
How do I stop a thread that waits for long periods (e.g., for input)?
For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation:
Thread.currentThread().interrupt();
This ensures that the Thread will reraise the InterruptedException as soon as it is able.
I would consider it a bad practice or at least a bit risky.
Usually higher level methods do not perform blocking operations and they will never see InterruptedException there. If you mask it in every place you perform interruptible operation, you will never get it.
The only rationale for Thread.currentThread.interrupt() and not raising any other exception or signaling interrupt request in any other way (e.g. setting interrupted local variable variable in a thread's main loop) is the situation where you really can't do anything with the exception, like in the finally blocks.
See Péter Török's answer, if you want to better understand implications of the Thread.currentThread.interrupt() call.
Refer from java doc
If this thread is blocked in an invocation of the wait(), join(),
sleep(long), then its interrupt status will be cleared and it will
receive an InterruptedException.
If this thread is blocked in an I/O operation, the thread's interrupt
status will be set, and the thread will receive a
ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt
status will be set and it will return immediately from the selection
operation.
If none of the previous conditions hold then this thread's interrupt
status will be set.
So, if you change the sleepBabySleep() method in #Ajay George Answer to I/O operation or just a sysout, you don't have to set the status back to stop the program. (BTW, they don't even throw InterruptedException)
Just like #Péter Török said => This is done to keep state. (And particular for method that will throw InterruptedException)
GAE just blocks forever when I try to terminate an ExecutorService. Small sample below:
ThreadFactory threadFactory = ThreadManager.currentRequestThreadFactory();
ExecutorService pool = Executors.newSingleThreadExecutor(threadFactory);
Future<String> future = pool.submit(new Callable<String>() {
public String call() throws Exception {
return "Hello from Thread";
}
});
LOG.info("Result is: [" + future.get() + "]. Pool expected to be idle now");
pool.shutdown();
if (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
LOG.info("Pool does not like shutdown()");
pool.shutdownNow();
if (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
LOG.info("Pool does not even like shutdownNow()");
}
}
The same code works without blocking when running locally, it just blocks without terminating when running deployed on AppEngine. The timeout can be increased until the 60 second request limit forces the code to interrupt.
This seems to be a subtle yet dangerous difference to a standard JVM. Code found regularly to clean up can essentially kill your service. ThreadManager documentation mentions that the threads are a bit special but they are -as far as I understand - interruptible and meant to terminate.
Is it just me (some library messing with threads)?
Is it a bug / feature / somewhere documented?
Since waiting for termination is just pointless, is it okay to just call pool.shutdown(), then assume all is going to be okay? Running threads are a good way to leak memory..
Update #1
I'm even more confused after some more testing. All works fine when using a Thread directly. Slightly convoluted example:
final CountDownLatch threadEnter = new CountDownLatch(1);
final Object wait4Interrupt = new Object();
Runnable task = new Runnable() {
public void run() {
synchronized (wait4Interrupt) {
threadEnter.countDown();
try {
wait4Interrupt.wait();
} catch (InterruptedException e) {
// expected to happen since nothing is going to notify()
LOG.info("Thread got interrupted.");
Thread.currentThread().interrupt();
}
}
}
};
Thread thread = ThreadManager.createThreadForCurrentRequest(task);
// not started state
LOG.info("Thread log #1: " + thread + " " + thread.getState());
thread.start();
threadEnter.await();
// thread is inside synchronized / already waiting
synchronized (wait4Interrupt) {
// => guaranteed that thread is in waiting state here
LOG.info("Thread log #2: " + thread + " " + thread.getState());
thread.interrupt();
}
thread.join(1000);
// thread is dead
LOG.info("Thread log #3: " + thread + " " + thread.getState());
Logs produced:
I 16:08:37.213 Thread log #1: Thread[Thread-7,5,Request #0] NEW
I 16:08:37.216 Thread log #2: Thread[Thread-7,5,Request #0] WAITING
I 16:08:37.216 Thread got interrupted.
I 16:08:37.217 Thread log #3: Thread[Thread-7,5,] TERMINATED
The thread returned by the factory isn't started, it supports wait & interrupt just fine and it can be join()'d and is terminated afterwards. What else would an ExecutorService want to do?
Update #2
pool.toString() from example #1 after shutdown() results in
java.util.concurrent.ThreadPoolExecutor#175434a
[Shutting down, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
which also indicates that it's not an issue caused by unterminated threads since it states active threads = 0.
Update #3
Pools do shutdown nicely when being told to do so before they finished their task. The following terminates correctly after 500 ms. Adding future.get() will show the original problem again.
Future<String> future = pool.submit(new Callable<String>() {
public String call() throws Exception {
// sleep a bit so pool is "busy" when we're trying to shutdown.
Thread.sleep(500);
return "Hello from Thread";
}
});
// get here = evil
pool.shutdown();
pool.awaitTermination(2, TimeUnit.SECONDS);
=> Issue seems to occur on idle pools only. Busy pool can be shutdown.
You are right, Threads on App Engine are interruptible. Quoting from the official docs:
An application can perform operations against the current thread, such as thread.interrupt().
Since it is working fine locally, it is a difference between the development server and the sandbox at production environment.
I think the development server allows multi-threaded execution if not disabled while the production environment requires to explicitly state it in the application config file (appengine-web.xml):
<threadsafe>true</threadsafe>
Unless you explicitly state your app is thread-safe, serving a request can only use 1 thread therefore your ExecutorService cannot start a new Thread to execute the task you submitted and therefore future.get() will block. It would block until the "current" thread would end but obviously that could only happen after serving the request, so you have a deadlock here.
Have a look at the following snippet with the comments :
try {
Thread.sleep(20000); // Foo thread sleeps for 20 seconds
System.out.println("After the sleep statement");
} catch(Exception exc) {
exc.printStackTrace();
}
// It has been 12 seconds since the thread went to sleep and....I interrupt
Foo.interrupt(); // exception gets thrown and the code in the catch block gets executed
Is there any way I can execute the next statement after the sleep statement ? I want to awaken the thread at some time and want it to continue it work . Is there any thought/method for this ?
Not sure if this is what you want?
try {
Thread.sleep(20000); // Foo thread sleeps for 20 seconds
System.out.println("After the sleep statement");
} catch(InterruptedException exc) {
System.out.println("Sleep was interrupted");
} catch(Exception exc) {
exc.printStackTrace();
}
sleep() throws InterruptedException when it is interrupted. So "Sleep was interrupted" will be printed on interrupt() while "After the sleep statement" is called only if sleep() managed to sleep configured 20 seconds.
If you don't care whether sleep() returned normally or thrown and just continue your work, wrap it with empty try-catch:
public void interruptibleSleep(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException exc) {}
}
and then instead of Thread.sleep(20000) call interruptibleSleep(20000):
interruptibleSleep(20000);
System.out.println("After the sleep statement");
I think you're confused. Here's what happens
public void run() {
// This executes as soon as the thread is run
try {
// We decide to sleep for UPTO 20 seconds
Thread.sleep(20000);
// Code here executes ONLY if we managed to sleep for 20 seconds without
// interruption
} catch(InterruptedException exc) {
// Code here executes ONLY if we were interrupted
} catch(Exception exc) {
// This shouldn't ever execute in theory
}
// Code here ALWAYS executes after the sleeping (and ONE of the two blocks)
// whether or not it was interrupted.
}
There is a very well phrased paragraph at The Java Tutorials
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate. This is the usage emphasized in this lesson.
Stopping and staring threads reliably is an important part of designing concurrent applications. And even though you could repurpose interrupts to do whatever you want, your code will be more reliable and easier to maintain for others if you leave interrupt for it's most common purpose - requesting that the thread exit. This is something you will probably want to do if the user decides to shutdown the app before the 20 second timeout is finished.
So how to solve the original problem - allowing one thread to indicate to another that it is time to get to work. The class below shows how a CountDownLatch might be used to solve this problem.
The new Foo:
class Foo extends Thread
{
CountDownLatch latch = new CountDownLatch(1);
#Override
public void run()
{
try
{
boolean early = latch.await(20, TimeUnit.SECONDS);
System.out.println("Doing work " + (early ? "right away" : "after delay"));
// do real work here...
}
catch (InterruptedException e)
{
System.out.println("Interrupt detected. Exiting thread...");
}
}
public void goAhead()
{
latch.countDown();
}
}
We get rid of the "Sleep" and replace it with a call to the await method of the latch object. To make foo do work, invoke:
foo.goAhead(); // prints out "Doing work right away"
This causes the latch to countdown. The call to "await" will immediately exit without throwing an exception and returning true.
To shut down foo, use:
foo.interrupt(); // prints out "Interrupt detected..."
This will cause await to throw an InterruptedException just like sleep.
Or do nothing. The call to await times out after 20 seconds, does not throw an exception and returns false. Foo prints out "Doing work after delay"
One long term advantage of this design as that while you are "doing work" you may need to call other blocking methods. Interrupt can still be used to interrupt any of them and help you on your way to shutting down the thread reliably in response to unexpected events.
As the title showed, If Future.get(timeout) timeout, does the thread continue running,
ExecutorService executor = Executors.newFixedThreadPool(n);
Callable<Object> task = new Callable<Object>() {
public Object call() {
//...
}
}
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
}
If the thread continue to run and get blocked due to some IO, etc, then when the threadpool get full, not new task can be sumitted, which means the trheadpool gets stuck, since all the threads in the pool are blocked, right?
The call to future.get(..) will block the thread running it for up to 5 seconds. The task executed by the thread pool will be unaffected, and will continue running until a graceful termination / exception / interruption.
Regarding the submission of new tasks when the thread pool is in full capacity, in your case the tasks WILL be submitted (releasing the submitter thread immediately), but will wait in the thread pool queue for execution. The API documentation of Executors.newFixedThreadPool(..) specifies this clearly.
Right, underlaying thread will be live until IO thrown an exception or ended.