I am creating a task poller which looks for tasks every minute. It looks like this:
public class Poller {
private final ExecutorService e = Executors.newSingleThreadExecutor();
public void start() {
e.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
final Task task = manager.getTask();
if (task != null) {
// ...
} else {
try {
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
}
public void stop() {
e.shutdownNow();
}
}
When I want to stop the poller process, I exucute stop(). This triggers an interrupt on the running thread, which will stop the poller.
This works fine. However, I am wondering if there is a possibility that this thread will be interrupted by someone else, most likely the JVM. In that case, the poller will quit while it shouldn't.
I know we can have spurious wakeups, so we have to guard a wait() with a while (condition) { ... } instead of if (condition) { ... }. Can it also occur that the JVM will interrupt an ongoing thread for no good reason?
In that case, I should introduce a volatile boolean and check on that instead of while (!Thread.currentThread().isInterrupted())?
Yes, you should be introduce a volatile boolean to control the loop. Not just because of the possibility of a spurious interrupt, but because it makes the code more readable.
You're not achieving a clever optimization by "saving" a boolean and using the interrupt status of the thread to control the loop, you're making it less obvious as to what the working mechanism of the class is.
Edit: I wasn't really answering the core question (mixed it up with wakeups). As we know, spurious wakeups can and do happen, which is why we use guard clauses/loops to check that a condition has really been satisfied.
Spurious interrupts aren't a thing, meaning there's always one thread interrupting another inside the Java ecosystem (unlike with wakeups, where the reason is external). Interrupting random threads is not something that the Java platform does by itself, but you could write a thread that just randomly selects other threads and tries to interrupt them. However that wouldn't be a spurious interrupt, that would be a malicious interrupt.
Related
I've a few questions around ExecutorService and the shutdown process.
My use case:
I use an ExecutorService to spawn a fixed number of threads whose run method look like this:
while (true) {
try {
this.currentThreadRunning = true;
processMessage();
}
catch (Throwable e) {
// Keeping the thread alive despite exceptions.
}
}
These threads run infinitely, polling for messages.
What am I trying to do?
I am polling an SQS queue for messages and processing them.
Obviously, in my case, the ExecutorService's shutdown method would not work. When shutdownNow() is called, all my threads are shutdown unceremoniously. I hate it!
Is there a way to invoke awaitTermination and verify, in my Runnable instance(in a finally block?), if shutdown has been initiated and trigger the same for the current thread?
UPDATE: I've refactored my code to perform polling and then spawning threads to process them. Thus, the Runnable instance's run method need not be an endless loop. And awaiTermination will lead to a definite closure of the threads. And to be sure, I've triggered shutdownNow after awaitTermination.
I think what you are doing is conceptually wrong.
awaitTermination is meant to wait for all threads to finish naturally and then stop the executor. When submitting a Runnable, it shouldn't have an idea of the context of it's execution, so, coupling your runnable to your executor is not a good idea IMHO.
Maybe you should look into the Future class and move your Runnable implementation there. Then you will be forced to implement a cancel(boolean) method which you might find useful.
What is exactly your use case? Maybe if you explain it, the community can point out a better suited implementation.
For infinitely running Runnables I rely on catching an InterruptedException, which will typically be thrown from my calling shutdownNow() or occasionally from calling Future#cancel(true)
while(!Thread.interrupted()) {
try {
} catch(InterruptedException e) {
break;
} catch(Throwable e) {
// Keeping the thread alive despite exception
}
}
// Thread was interrupted via shutdownNow(), cleanup resources
If I need to distinguish between a resumable interrupt and a shutdown interrupt then I share an AtomicBoolean doShutdown among my Runnables that is initialized to false and set to true if I want an InterruptedException to terminate the thread.
You have to check the interrupt status of the thread you are running in (see tutorial on interrupts here: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html). Your code should be:
while (!Thread.currentThread().isInterrupted()) {
try {
this.currentThreadRunning = true;
processMessage();
}
catch (Throwable e) {
// Keeping the thread alive despite exceptions.
}
}
Note however that you do have to handle interrupts correctly in code called from your runnable. If there is anything like the following:
try {
// do something
} catch(InterruptedException e) {
// ignore
}
then this won't work. The correct way to handle InterruptedException is to call Thread.currentThread().interrupt();.
You should not call shutdownNow() But you should only call shutdown and use awaitTermination to wait for some time.
So shutdown would be something like this
Declare a volatile variable
private volatile stopThread = false;
On shutdown you call
this.stopThread = true;
executor.shutdown();
executor.awaitTermination(..
executor.shutdownNow() // in case termination takes too long
And in the thread you check for the stopThread variable. You cannot use isInterrupted here because we are not interrupting the thread. we are just waiting for the thread to exit based on this condition
if(stopThread){
// calling off all the operations and returning
}
I have written an article about shuting down the executorservice properly
http://programtalk.com/java/executorservice-not-shutting-down/
I hope this will help you.
I want to start a thread and cancel it if it doesn't finish within 5 seconds:
private final class HelloWorker implements Callable<String> {
public String call() throws Exception {
while(true) {
if (Thread.isInterrupted()) {
return null;
}
}
return performExpensiveComputation();
}
private String performExpensiveComputation() {
// some blocking expensive computation that may or may not take a very long time
}
}
private ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
Future<String> future = executorService.submit(new HelloWorker());
try {
String s = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("cancelled: " + future.isCancelled() + "done: " + future.isDone());
executorService.shutdown();
try {
System.out.println("try to terminate: " + executorService.awaitTermination(60, TimeUnit.SECONDS));
} catch (Exception ex) {
// ignore
}
}
However it looks like the awaitTermination returns false. Is there a way for me to check why an ExecutorService won't terminate? Can I figure out what threads are still running?
There is no safe way to stop a running thread without disturbing the stability of the rest of the process. This is why Thread#stop has been deprecated a long time ago, and why Executor Services only use the soft, cooperative Thread#interrupt mechanism.
Your thread will have to actively check if an interrupt has been requested and perform proper cleanup before ending. Alternatively, the thread will call some interruptible JDK methods, which will throw InterruptedException, which the tread will properly honor and end itself.
Why Future.cancel() doesn't work the way you think it does
Future cancel removes the task from the running queue. If your task is already running it won't stop it. So cancel() is a different concept that interrupting. As the Javadocs say:
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, has already been cancelled, or could
not be cancelled for some other reason. If successful, and this task
has not started when cancel is called, this task should never run. If
the task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/concurrent/Future.html#cancel(boolean)
What you are asking is how to interrupt. Fortunately, when you call Future.cancel() it will call the interrupt method. But you'll need to allow it with the mayInterruptIfRunning flag and will need to handle interrupts correctly (see below).
Why interrupt?
Interrupting threads in Java is useful when you have a long running task that you now need to stop, or when you have a daemon that you need to turn off, and other examples.
How to interrupt
To interrupt you call interrupt() on the thread. This is a cooperative process, so your code has to be ready for it. Like this:
myThread.interrupt();
Responsible code
Your code's responsibility is to be ready for any interruptions. I'd go so far to say that whenever you have a long running task, that you insert some interrupt ready code like this:
while (... something long...) {
... do something long
if (Thread.interrupted()) {
... stop doing what I'm doing...
}
}
How to stop what I'm doing?
You have several options:
If your you are in Runnable.run() just return or break out of the loop and finish the method.
You may be in some other method deep in the code. It may make sense at that point for that method to throw InterruptedException so you would just do that (leaving the flag cleared).
But maybe deep in your code it doesn't make sense to throw InterruptedException. In that case you should throw some other exception, but before that mark your thread interrupted again so the code that catches knows that an interrupt was in progress. Here's an example:
private void someMethodDeepDown() {
while (.. long running task .. ) {
... do lots of work ...
if (Thread.interrupted()) {
// oh no! an interrupt!
Thread.currentThread().interrupt();
throw new SomeOtherException();
}
}
}
Now the exception can propagate an either terminate the thread or be caught, but the receiving code hopefully notices that an interrupt is in progress.
Should I use isInterrupted() or interrupted()
You should prefer interrupted() because:
Your code should reset the interrupt flag because if you don't the thread you are using could go back to a thread pool with an interrupted state causing problems (of course, that's a bug in the thread pool code, you won't get that behavior if you use Executors.newFixedThreadPool() for example. But other threading code could have it.
As another answer stated, the clearing of the interrupted flag indicates that you've received the message and are taking action. If you leave it on true, the after a while caller can assume you won't respond to it in a timely manner.
Why interrupt() why not some other flag in my code?
Interrupt is the best mechanism for interruption because our code can be ready for it. If we find code that is just catching and ignoring the InterruptExceptions or not checking for interrupted() in its body then we can correct those mistakes and make our code always cleanly interruptible without creating arcane dependencies on non-standard mechanisms in your code.
Unfortunately Joshua Block proposed the opposite in his famous book Effective Java, Second Edition. But enabling the interrupt() method to work as intended is much better, because this code is used by the Java standard library as explained above. A custom interruption method would not be.
This IBM developerWorks article states:
“The one time it is acceptable to swallow an interrupt is when you know the thread is about to exit. This scenario only occurs when the class calling the interruptible method is part of a Thread, not a Runnable […]”.
I always implemented Runnable for my threads by now. Giving a Runnable implementation like this:
public class View() implements Runnable {
#Overload
public void run(){
Thread worker = new Thread(new Worker());
worker.start();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
worker.interrupt();
// Thread.currentThread().interrupt();
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement? Doesn’t return; perform a clean enaugh exit already? What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”. What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown? Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
BTW, is it a better code design to extend Thread instead of implementing Runnable?
It resets the interrupt flag. This JavaSpecialists newsletter covers this confusing topic in more detail.
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
So if you know that your code is not going to be used by another component, then you don't need to re-interrupt. However I really wouldn't make that minor optimisation. Who knows how your code is going to be used/reused in the future (even by copy/paste) and consequently I would reset the flag for every interrupt.
Here is an example where return it is not enough:
public void doSomething1() {
while (someCondition1()) {
synchronized {
try {
this.wait();
} catch (InterruptedException e) {
return; // Should be Thread.currentThread().interrupt();
}
}
}
}
public void doSomething2() {
while (someCondition2()) {
doSomething1();
}
}
As the exception throw clears the interrupted state next time doSomething1() is executed the status is cleared and the thread does not terminates.
I prefer extending Thread because it gives you a better understanding of what the thread is doing, but it is not necessarily better code design.
As Brian stated ,it resets the interrupt flag but that doesn't say much. In your case it will do nothing and the View-Thread will keep on running.
When interrupting a Thread, the standard procedure is that the Thread should stop running. It won't do this automatically and you have to implement a way to stop it once it is interrupted.
Using the built-in functionality there are two options:
Have the main loop inside the try-block for the InterruptedException. This way, when it is interrupted you you will be thrown out of the loop and the method will exit.
The above can be bad if you have to save the state as it may corrupt the state. As an alternative, you can set the interrupted-flag (as said when it's thrown. re-interrupt it Interrupt the Thread
Either way, you have to check that the Thread is interrupted in your while-loop (with !Thread.currentThread().isInterrupted()-statement in the while-loop) or it may/will not exit. You're not fulfilling one of the first options and neither checking the flag, so your View-thread will keep on running after being interrupted.
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement?
As a point, I always do. We all copy-and-paste code and swallowing the interrupt is such a serious problem that I as a rule always do it, even if the thread is about to die.
Doesn’t return; perform a clean enough exit already?
If you are sure that it is the last return before the run() method completes and the thread exits, then yes, it not technically necessary. But see above. For posterity, return; doesn't do anything with the interrupt flag.
The question is whether your View class has been wrapped. Are you sure that when you return you are exiting the Thread. Maybe someone is delegating to it. AOP may be in place to do some sort of instrumentation.
What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”.
In general, it is important to not swallow the interrupt when your code is called by some sort of wrapping code (delegation, AOP, etc) which needs the interrupt flag. If you are swallowing it, the wrapper won't be able to use it. But in this case, there is no benefit.
What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown?
Nothing. Once the thread exits the interrupt state is worthless. And actually, it looks like the interrupt state isn't even persisted after the thread is dead.
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("caught");
}
}
});
thread.start();
thread.interrupt();
System.out.println(thread.isInterrupted());
thread.join();
System.out.println(thread.isInterrupted());
Prints:
true
caught
false
Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
I can't. There is no code outside of the thread's run() method unless someone is wrapping your runnable in other code without your knowledge.
This may happen if you are using an ExecutorService but in that case the thread's interrupt status is specifically cleared with a wt.isInterrupted() before the job is run.
So again, the reason is to do is is because it's a good pattern and that's what's important in software engineering.
I am trying to close all my thread in my threadpool.
Usually I try:
while(!Thread.currentThread().isInterrupted()) {...
To close the while loop...
But I have one Thread which only consists about
while(!Thread.currentThread().isInterrupted()) {//which is true
This is how I close the threads:
pool.shutdownNow();
So how would you close such a Thread?
You can add a volatile boolean flag.
public class Worker implements Runnable {
volatile boolean cancel = false;
#Override
public void run() {
while (!cancel) {
// Do Something here
}
}
public void cancel() {
cancel = true;
}
}
Now you can just call
worker.cancel();
Update:
From Java doc of shutdownNow()
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
here are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
So either you will have to define your interruption policy by preserving the interrupts
catch (InterruptedException ie) {
// Preserve interrupt status
Thread.currentThread().interrupt();
}
Instead of that you might use a self created flag as condition for the while loop.
public class MyClass implements Runnable
{
private volatile boolean running = true;
public void stopRunning()
{
running = false;
}
public void run()
{
while (running)
{
}
// shutdown stuff here
}
}
Now, to stop it, just call:
myClassObject.stopRunning();
This will let the code finish normally.
If you have implemented this as you have described, it should just work.
When you call pool.shutdownNow() it is supposed to interrupt all worker threads that are currently active. Assuming that the application specific run() methods check the interrupted flag and terminate themselves when they find it set, your threads should shutdown.
There is really no need to add a different mechanism using an ad hoc cancel flag ... or some such.
Incidentally, there are a couple reasons why interrupt() is better than ad hoc cancellation:
Standard APIs like ExecutorService use it.
Various low-level API methods like sleep, wait, join and some I/O methods are sensitive to it.
If you are using a java.util.concurrent ExecutorService implementation, then it will definitely send an interrupt signal to all the threads in its thread pool. The problem with your rogue task may be that the loop doesn't in fact iterate, but blocks somewhere within, so the interrupted status is not getting checked at all.
Yet another problem you may have: the while loop runs some code that catches InterruptedException without handling it properly, effectively swallowing the interrupt signal. This is a common coding mistake and in most cases due to the ugly truth that InterruptedException is checked.
I have a system with multiple threads running - my main-thread just checks if there are jobs to be done and if there are some, it calls the sub-threads (notifyAll()) who will execute it. After that, the sub-threads just wait() until there are some new tasks.
Actually, the thread-system is running reliable, but after a longer runtime (3-5h), some sub-threads just die without a warning or an error. They just exit one after another - but again only with a time-range of 2-x hours. I have used jconsole to check this phenomenon, which threads are running and how they just simply disappear.
Furthermore, the main-thread is executing every second, but the sub-threads are mainly wait()ing and are not often used at all (since there are not so many tasks in the test environment).
The only reason I can think of is, that the JVM turns off the sub-threads since they are not often used enough?
I would be very thankfull for your help!
P.S. All threads are not defined as daemons and the main-thread just works fine!
edit
Thanks for your answers, but I actually use this loop.
public void addTask (Task in_task) throws InterruptedException {
synchronized (tasks) {
while (tasks.size() == MAXIMUM_NUMBER_OF_TASKS) {
tasks.wait();
}
tasks.offer(in_task);
tasks.notifyAll();
}
}
I use this loop, so that only some speciall amount of tasks will be executed.
The documentation for Object.wait() says:
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
Maybe you didn't follow this advice and got a spurious wakeup or interrupt?
Instead of writing your own multi-threaded task execution solution you could use java.util.concurrent.ThreadPoolExecutor. This would probably be a good idea no matter whether you are able to fix this bug or not.
I recommend using one of the Executors for managing your tasks. There are less chances that you will lose a possible error or exception in one of you sub-threads, so it should help you debug you program. Any exception that happens in a sub-thread will be stored inside the Future object and rethrown as an ExecutionException when you call Future#get().
List<Future<Void>> taskResults = new ArrayList<Future<Void>>();
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
while(!finished){
//say you wait (blocking) for a new task here
Callable<Void> task = getNextTask();
//put the task into the pool
Future<Void> result = es.submit(task);
taskResults.add(result);
}
//3 hours later, set `finished` to true
//at the end check that no exceptions were thrown
for(Future<Void> result : taskResults){
try{
result.get();
}catch(ExecutionException e){
//there was an error
e.getCause().printStackTrace();
}catch(InterruptedException e){
//irrelevant
}
}
In general, stuff in the java.util.concurrent helps you write much more robust multi-threaded applications, without having to resort to Object#wait() and other concurrency primitives (unless you are learning, of course).
Try setting an uncaught exception handler on each thread.
There is a setUncaughtExceptionHandler() function on the Thread. Implement the UncaughtExceptionHandler interface and print the exception.
General idea, but don't do it with anonymous classes/methods:
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
e.printStackTrace();
}
});