How to reset interrupted flag in executorservice.invokeAll() - java

I've learnt that it is the good practice to set Thread.interrupter() flag back to true after catching a InterruptedException.
However when I call executorService.invokeAll() and put a try clause around it, by catching the InterruptedException, will Thread.currentThread().interrupt() correctly flag the interrupted thread, or the main thread of my controller/runner?
public class Controller {
public void run() {
final List<Task> tasks = request.collectTasks()
try {
executorService.invokeAll(tasks);
} catch (InterruptedException e) {
message = "interrupted";
Thread.currentThread().interrupt();
throw new InternalFailureException(message);
}
}
}
class Task implements Callable<String> {
#Override
public String call() {
return taskId;
}
}
Overall is this the correct way to reset the interrupted flag?

In this code example you have given
try {
executorService.invokeAll(tasks);
} catch (InterruptedException e) {
message = "interrupted";
Thread.currentThread().interrupt();
throw new InternalFailureException(message);
}
whoever invokes Thread.currentThread().interrupt(); will set the flag of that thread in this example it will be the thread executing your Controller#run() method.
Ideally with executors it is the responsibility of Task or Runnable which gets scheduled over the executor to handle this flag properly.
Since it is a checked exception already - it will not give you an opportunity to decorate the task that you are about to submit inside executor so you have no easy control over it.

Related

Why is the statement in finally block still executed?

public class ADaemon implements Runnable {
#Override
public void run() {
try {
System.out.println("Starting ADaemon");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Exiting via InterruptedException");
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}}
result
Starting ADaemon
Exiting via InterruptedException
This should always run?
I tried to the code sample from "Thinking in Java" 4th edition, but it did't get the result as described in the book, the finally block is still being executed, why is that so? BTW I am using oracle jdk 10.0.1.
-------------update----------
It seems there is something run with my maven-runner plugin, I disabled it and it just get the same result as described in the book.
You say that the book says:
"the finally block may not be executed".
(Emphasis added.)
That is not the same as saying:
"the finally block will not be executed".
I think that the book is implying that it is unspecified (and possibly JVM specific) whether daemon thread gets an interrupt (or something) when the application exits.
Certainly, if the daemon thread caught and ignored the "interrupted" exception as follows, then I would expect that the finally to never be executed.
public class ADaemon implements Runnable {
#Override
public void run() {
try {
System.out.println("Starting ADaemon");
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Caught InterruptedException");
}
}
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}
}
I would expect similar behavior if the daemon thread was not executing interruptible code.
This should always run? Yes. Unless the JVM actually halts the finally block is guaranteed to be entered. Something like
System.exit(-1);
in the catch block will prevent that. If that is what you want. It will also stop the JVM! The book is warning you that if all other threads are completed, the daemon thread may never be scheduled before the JVM terminates. You are directly calling start(). Consider using
SwingUtilities.invokeLater(t);
It probably won't run unless you remove t.setDaemon(true);
The finally block is a powerful (and dangerous if used incorrectly) tool which will almost always run after the try or catch block completes (despite some small cases which are highlighted above).
Look at this example:
try{
throw new Exception();
}catch(Exception e){
return;
}finally{
System.out.println("Shouldn't run?");
}
If this was in a method, the finally block would still be executed (never do this as it is a bad practise). It is designed to perform any cleanup despite the result of the operation you did such as closing streams (which can now be done automatically through paranthesis in the statement 'try').

Why does BoundedExecutor have to catch RejectedExecutionException?

As to BoundedExecutor in the book Java Concurrency in Practice, task submission has been throttled by semaphore. When would the underlying executor throw a RejectedExecutionException? Maybe when operating system runs out of threads?
public class BoundedExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command) throws InterruptedException, RejectedExecutionException
{
semaphore.acquire();
try {
exec.execute(new Runnable() {
#Override public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
}
Part of the contract of Executor.execute() is that it can throw a RejectedExecutionException:
if this task cannot be accepted for execution
What that means for any given Executor implementation is up to the discretion of that implementation. I could create an OnlyOnSundaysExecutor that rejects tasks unless the current day of the week is Sunday. You would have to check the documentation for the various Executor implementations to see under what circumstances they would throw a RejectedExecutionException exception.
Regardless of the circumstances under which an exception might be thrown, it is important to keep your application in a consistent state, even when exceptions occur.
Here, the semaphore that has been acquired should always get released. For most resources that should get released under all circumstances, you would use a try {} finally { /* release action */ } construct to ensure the release even in the exceptional case, but here, we have the special situation that the release action should be performed only in the exceptional case, as in the successful case, the submitted Runnable will perform the release action (note that within the Runnable, finally is indeed being used).
So the code is supposed to handle the case when a RejectedExecutionException is thrown. We might want to do that for every RuntimeException or Error, but the problem is, RejectedExecutionException is the only exception type where we know for sure that the runnable will never get executed. For all other kinds of exceptions, it is possible that it will still run.
To make the cleanup safe, you would need another atomic toggle:
public void submitTask(final Runnable command) throws InterruptedException {
AtomicBoolean proceed = new AtomicBoolean(true);
semaphore.acquire();
try {
exec.execute(new Runnable() {
#Override public void run() {
if(proceed.compareAndSet(true, false)) try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch(Throwable e) {
if(proceed.compareAndSet(true, false)) semaphore.release();
throw e;
}
}
Now, in every exceptional case, an attempt to release the semaphore will be made, unless the Runnable flagged that it is already running. Or the Runnable will not proceed if it detects that the semaphore has been released due to an exception in the submitting code.
This is, of course, more complicated than the book example and possibly distracting from the original intent of the example. Also, it uses the Java 7 feature of being able to easily catch and re-throw all possible exceptions of the try block. This wasn’t available when the book was written.

Should I Thread.currentThread.interrupt() before I throw an exception back?

I am implementing an interface which throws IOException. In my implementation, I call another method which can block, and therefore throw InterruptedException.
Context:
I want to end the treatment if I am interrupted;
this is not a thread I created myself.
My current idea is to do as such (skeleton code):
#Override
public void implementedMethod()
throws IOException
{
try {
methodThatBlocks();
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
throw new IOException();
}
}
is that the correct way? Or should I just throw and not .interrupt()?
Yes, you should call interrupt() to let the calling code know that the thread has been interrupted. If you don't do it, since the InterruptedException clears it, the calling code will have no way to know about the interruption and won't stop running although it should.
Let me quote Java Concurrency in Practice:
Restore the interrupt. Sometimes you cannot throw InterruptedException, for instance when your code is part of a Runnable. In these situations, you must catch InterruptedException and restore the interrupted status by calling interrupt on the current thread, so that code higher up the call stack can see that an interrupt was issued,
as demonstrated in Listing 5.10.
public class TaskRunnable implements Runnable {
BlockingQueue<Task> queue;
...
public void run() {
try {
processTask(queue.take());
} catch (InterruptedException e) {
// restore interrupted status
Thread.currentThread().interrupt();
}
}
}
Of course not. The thread is already unblocked and running. In the code that is about to throw an exception. What would be the point?

FutureTask does not seem to interrupt

I am making some dummy programs to learn about this java class.
My timed task calls a task which does nothing giving it 3 secs time before interrupting it.
Here's the code:
FutureTask<Integer> task = new FutureTask<>(new
Callable<Integer>(){
#Override
public Integer call() throws Exception {
int i =0;
while(i<100000){
;
}
return 0;
}
});
executor.execute(task);
try {
task.get(3000, TimeUnit.MILLISECONDS);
System.out.println("Everything was ok");
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException ex){
boolean result = task.cancel(true); //here i cancel the thread
System.out.println("the task has timed out "+result);
}
What happens is that the catch block is executed, but my program keeps running until the thread finishes. It is like task.cancel was not accepted. Why is that?
Your task is compute-bound. It doesn't perform any IO or sleep, and that's when the JVM checks the interrupt flag (any method that throws a InterruptedException). Hence your task is uninterruptible.
It's worth reading the Interrupt tutorial. Note:
What if a thread goes a long time without invoking a method that
throws InterruptedException? Then it must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received. For example:
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
and also
The interrupt mechanism is implemented using an internal flag known as
the interrupt status. Invoking Thread.interrupt sets this flag. When a
thread checks for an interrupt by invoking the static method
Thread.interrupted, interrupt status is cleared. The non-static
isInterrupted method, which is used by one thread to query the
interrupt status of another, does not change the interrupt status
flag.
Note that quite often people will write something like:
try {
// interruptible operation
}
catch (InterruptedException e) {
// do nothing
}
which doesn't reset the interrupted flag. This results in uninterruptible code. See this JavaSpecialists newsletter for more info

Thread Blocks in server mode

This method notifes an event loop to start processing a message. However, if the event loop is already processing a message then, this method blocks until it receives a notification of completed event processing (which is triggered at the end of the event loop).
public void processEvent(EventMessage request) throws Exception {
System.out.println("processEvent");
if (processingEvent) {
synchronized (eventCompleted) {
System.out.println("processEvent: Wait for Event to completed");
eventCompleted.wait();
System.out.println("processEvent: Event completed");
}
}
myRequest = request;
processingEvent = true;
synchronized (eventReady) {
eventReady.notifyAll();
}
}
This works in client mode. If I switch to server mode and the time spent in the event loop processing the message is too quick, then the method above blocks forever waiting for the event to completed. For some reason the event complete notification is sent after the processingEvent check and before the eventCompleted.wait(). It makes no difference if I remove the output statements. I can not repeat the same problem in client mode.
Why does this only happen in server mode and what can I do to prevent this happening?
Here is the eventReady wait and eventCompleted notification:
public void run() {
try {
while (true) {
try {
synchronized (eventReady) {
eventReady.wait();
}
nx.processEvent(myRequest, myResultSet);
if (processingEvent > 0) {
notifyInterface.notifyEventComplete(myRequest);
}
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
notifyInterface.notifyException(e, myRequest);
} finally {
processingEvent--;
synchronized (eventCompleted) {
eventCompleted.notifyAll();
}
}
} // End of while loop
} catch (InterruptedException Ignore) {
} finally {
me = null;
}
Here is revised code which seems to work without the deadlock problem - which BTW happened in client mode randomely after about 300 events.
private BlockingQueue<EventMessage> queue = new SynchronousQueue<EventMessage>();
public void processEvent(EventMessage request) throws Exception {
System.out.println("processEvent");
queue.put(request);
}
public void run() {
try {
while (true) {
EventMessage request = null;
try {
request = queue.take();
processingEvent = true;
nx.processEvent(request, myResultSet);
notifyInterface.notifyEventComplete(request);
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
notifyInterface.notifyException(e, request);
} finally {
if (processingEvent) {
synchronized (eventCompleted) {
processingEvent = false;
eventCompleted.notifyAll();
}
}
}
} // End of while loop
} catch (InterruptedException Ignore) {
} finally {
me = null;
}
}
If you call notifyAll and no thread is wait()ing, the notify is lost.
The correct approach is to always change a state, inside the synchronized block, when calling notify() and always check that state, inside the synchronized block, before calling wait().
Also your use of processingEvent doesn't appear to be thread safe.
Can you provide the code which waits on eventReady and notifies eventCompleted?
Your program can happen to work if your speed up or slow down your application just right e.g. if you use -client, but if you use a different machine, JVM or JVM options it can fail.
There are a number of race conditions in your code. Even declaring processingEvent volatile or using an AtomicBoolean won't help. I would recommend using a SynchronousQueue which will block the event until the processer is ready for it. Something like:
private final BlockingQueue<Request> queue = new SynchronousQueue<Request>();
...
// this will block until the processor dequeues it
queue.put(request);
Then the event processor does:
while (!done) {
// this will block until an event is put-ed to the queue
Request request = queue.take();
process the event ...
}
Only one request will be processed at once and all of the synchronization, etc. will be handled by the SynchronousQueue.
If processingEvent isn't declared volatile or accessed from within a synchronized block then updates made by one thread may not become visible to other threads immediately. It's not clear from your code whether this is the case, though.
The "server" VM is optimised for speed (at the expense of startup time and memory usage) which could be the reason why you didn't encounter this problem when using the "client" VM.
There is a race condition in your code that may be exasperated by using the server VM, and if processingEvent is not volatile then perhaps certain optimizations made by the server VM or its environment are further influencing the problem.
The problem with your code (assuming this method is accessed by multiple threads concurrently) is that between your check of processingEvent and eventCompleted.wait(), another thread can already notify and (I assume) set processingEvent to false.
The simplest solution to your blocking problem is to not try to manage it yourself, and just let the JVM do it by using a shared lock (if you only want to process one event at a time). So you could just synchronize the entire method, for instance, and not worry about it.
A second simple solution is to use a SynchronousQueue (this is the type of situation it is designed for) for your event passing; or if you have more executing threads and want more than 1 element in the queue at a time then you can use an ArrayBlockingQueue instead. Eg:
private SynchronousQueue<EventMessage> queue = new SynchronousQueue<EventMessage>();
public void addEvent(EventMessage request) throws Exception
{
System.out.println("Adding event");
queue.put(request);
}
public void processNextEvent()
{
EventMessage request = queue.take();
processMyEvent(request);
}
// Your queue executing thread
public void run()
{
while(!terminated)
{
processNextEvent();
}
}

Categories