How to tell a Runnable to throw an InterruptedException? - java

I'm writing a scheduler which accepts a Runnable which is either queued for synchronous or asynchronous execution.
I would like to be able to implement a SomeScheduler.interrupt(int taskId) which causes a InterruptedException() to be thrown from within the thread.
Is this possible or am I going about this all wrong?

Threads can be interrupted, a Runnable is just class that implements the run method.
On it's own it doesn’t belong to a thread, if you want to interrupt the execution of the runnable you need to interrupt it's calling thread.
The typical way this is done is to use an ExecutorService. When you submit a runnable or callable to the executor service it will return a Future you can then interrupt a particular task by using the Future#cancel method.
Note that simply interrupting the thread doesn’t cause InterruptedException to be thrown unless the thread is running code that checks the interrupt status and throws InterruptedException, for example the Thread#sleep method.

Related

How to stop / kill multiple threads after a Time-Out value in java

I want to stop / kill all Threads (Runnables) started by Main after a given timeout. I tried to do as mentioned below. But it is not working as expected. Apart from that, I tried with the Thread.interrupt() but the results is negative. I tried thread.stop(). It is working but deprecated.
Can anyone give some idea on this?
Note : I'm focusing on a solution for Runnables not Callables. And I'm trying to do this bymodifying only the client code (Main). Not the Threads (Supplier)
Main
Thread roxtoursThrd = new Thread(new Supplier("roxtours", 1));
Thread bluevacationsThrd = new Thread(new Supplier("bluevacations", 1));
Thread elixerThrd = new Thread(new Supplier("elixer", 1));
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
taskExecutor.execute(roxtoursThrd);
taskExecutor.execute(bluevacationsThrd);
taskExecutor.execute(elixerThrd);
taskExecutor.shutdown();
// taskExecutor.shutdownNow(); // This is also not stopping threads. They continue.
try {
taskExecutor.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Supplier.java
public class Supplier implements Runnable {
public Supplier(String name, int count) {
this.name = name;
this.count = count;
}
#Override
public void run() {
try {
// Some time consuming operations (URL Connections, XML Decoding, DB Queries etc etc) are goes in here.
} catch (Exception e) {
e.printStackTrace();
}
}
String name = null;
int count = 0;
Logger logger = Logger.getLogger(Supplier.class);
}
Making the executor's tasks respond to interruption will require changing the code for the Suppliers. Interruption is cooperative; the thread being interrupted gets a flag set on it, but it's up to the thread to decide how to handle it. If your Runnable doesn't act on it, as in your example, then nothing happens, the thread just keeps on executing.
The Executor can only cancel threads that respond to interruption, see the API documentation for ExecutorService.shutdownNow:
There 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.
A thread can check its flag with the Thread#isInterrupted method. Your Runnable task should check Thread.getCurrentThread().isInterrupted().
If a thread is waiting or sleeping when the interrupted flag is set then an InterruptedException will be thrown and the flag will be cleared.
Do not use Thread#setDaemon(true) unless you're prepared for those threads to disappear suddenly with no warning and no chance to clean up pending tasks when the rest of the application shuts down.
The other option is the deprecated Thread#stop method, which causes ThreadDeath to be thrown. Unlike interruption, this is not cooperative, and it's between difficult and impossible to write code that can predictably and cleanly terminate when this exception occurs, because ThreadDeath can be thrown anywhere, unlike InterruptedException, which is much more manageable since it is only thrown from specific blocking calls.
Use shutdownNow() instead of shutdown().
The shutdown() will initiate the shutdown and it will not accept any new tasks but you never know when the threads will be actually stopped.
The shutdownNow() will immediately attempts to stop all the active threads and this will return all the active threads which are awaiting for execution.
Again there is no guarantee that all the threads will be stopped immediately (Threads will go for a graceful shutdown and it may take time based on the task given to the thread). We have to use either of the below methods to wait till all the threads are completed its execution.
executor.awaitTermination(...);
or
while (! executor.isTerminated()) {
// Sleep for few milliseconds...
}
Refer the doc: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdown%28%29
Your thread's run method is not blocking, hence it does not run into a situation where an InterruptedException is thrown.
When a Thread is inerrupted, besides throwing an exception if it is blocking, it also has its interrupted status set, that is to say the method Thread#isInterrupted() returns true. Also, the method Thread#interrupted also returns true, but with the latter the interrupted status of the thread is cleared.
In your example you are not blocking nor are you checking the threads inerrupted status.
EDIT: Since you are not checking to see if the thread is interupted nor are you blocking, then you can't stop the threads explicitly, but you can stop them by making them daemon threads and then when your main thread (which is a user thread) finishes, all the other daemon threads will stop. Main difference between daemon thread and user thread is that as soon as all user thread finish execution java program or JVM terminates itself, JVM doesn't wait for daemon thread to finish there execution.
If you want to interrupt threads, you have to provide interruption entrance point. Sleep for a very short time, for example, then catch and handle InterruptionException.
Next what you can do is make use of isInterrupted() method in every iteration and the handle that as well.
Other approach would be to make all the threads daemons with setDaemon(), as they would be killed after main thread finishes, but this would be useful only if main was to be stopped.
In response to your edit/updated question:
excerpt from shutdownNow() documentation
There 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 prepare you application to work as multi-threaded or you stick to single thread.
Also, see How do you kill a thread in Java?.
And the most important link from the question above: http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

ScheduledExecutorService, how to stop action without stopping executor?

I have this code:
ScheduledExecutorService scheduledExecutor;
.....
ScheduledFuture<?> result = scheduledExecutor.scheduleWithFixedDelay(
new SomethingDoer(),0, measurmentPeriodMillis, TimeUnit.MILLISECONDS);
After some event I should stop action, which Declared in run() method of the SomethingDoer, which implements Runnable.
How can I do this? I can't shutdown executor, I should only revoke my periodic task. Can I use result.get() for this? And if I can, please tell me how it will work.
Use result.cancel(). The ScheduledFuture is the handle for your task. You need to cancel this task and it will not be executed any more.
Actually, cancel(boolean mayInterruptIfRunning) is the signature and using it with true parameter will cause a currently running exection's thread to be interrupted with the interrupt() call. This will throw an interrupted exception if the thread is waiting in a blocking interruptible call, like Semaphore.acquire(). Keep in mind that cancel will ensure only that the task will not be executed any more once it stopped the execution.
You can use the cancel() method from your ScheduledFuture object. Once cancelled, no further tasks will be executed.
If you want your currently running task to stop, you need to code your run method so it is sensitive to interrupts and pass true to the cancel() method to request an interrupt.

Why set the interrupt bit in a Callable

So, this resource (http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html) suggest to set the interrupt bit in a Thread when that Thread does not deal with the interrupt itself, "so that code higher up on the call stack can learn of the interruption and respond to it if it wants to."
Let's say I'm using an ExecutorService to run something in a different Thread. I construct a Callable and pass this Callable into ExecutorService.submit(), which returns a Future. If the Callable gets interrupted and then resets the interrupt bit, the associated Future will not throw an InterruptedException when Future.get() is called. So what would be the purpose of setting the interrupted bit in the Callable if this Future is the only way the main Thread has access to the spawned Thread.
class MyCallable implements Callable<String> {
#Override
public String call() {
while (!Thread.currentThread().isInterrupted()) {
}
Thread.currentThread().interrupt();
return "blah";
}
}
ExecutorService pool = makeService();
Future<String> future = pool.submit(new MyCallable());
// Callable gets interrupted and the Callable resets the interrupt bit.
future.get(); // Does not thrown an InterruptedException, so how will I ever know that the Callable was interrupted?
You are correct that the interrupt flag is not passed between the 2 threads in this scenario (that's how the built in ExecutorService was designed for whatever reason). If you want the main thread to see the interrupted status of the callable, then you must throw InterruptedException from your call method.
class MyCallable implements Callable<String> {
#Override
public String call() {
// ...
if(Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
return "blah";
}
}
Note, you still won't get InterruptedException directly from Future.get() in this scenario. since it was thrown by the callable, it will be wrapped in an ExecutionException (this is so you can distinguish between an interruption of the callable and an interruption of the main thread).
Interrupting a thread is supposed to terminate it, but in a less fragile way than kill(). The interrupted state of the thread is checked only during various blocking operations.
If your thread has been interrupted during one of these operations, an InterruptedException is thrown. When this happens, you want to exit cleanly, as quickly as you can. So, what should a Callable do if the executor service thread is interrupted?
If its action is short, one valid option is to just complete that action normally, but set the interrupted state on the thread so that the executor service will shut down after this action completes.
If the action is longer, you may want to instead throw an exception telling the caller that the action was interrupted.

Stop a Runnable submitted to ExecutorService

I've implemented subscription in my Java app. When new subscriber added, the application creates new task (class which implements Runnable to be run in the separate thread) and it is added to the ExecutorService like:
public void Subscribe()
{
es_.execute(new Subscriber(this, queueName, handler));
}
//...
private ExecutorService es_;
Application may register as many subscribers as you want. Now I want implement something like Unsubscribe so every subscriber has an ability to stop the message flow. Here I need a way to stop one of the tasks running in the ExecutorService. But I don't know how I can do this.
The ExecutorService.shutdown() and its variations are not for me: they terminates all the tasks, I want just terminate one of them. I'm searching for a solution. As simple as possible. Thanks.
You can use ExecutorService#submit instead of execute and use the returned Future object to try and cancel the task using Future#cancel
Example (Assuming Subscriber is a Runnable):
Future<?> future = es_.submit(new Subscriber(this, queueName, handler));
...
future.cancel(true); // true to interrupt if running
Important note from the comments:
If your task doesn't honour interrupts and it has already started, it will run to completion.
Instead of using ExecutorService.execute(Runnable) try using Future<?> submit(Runnable). This method will submit the Runnable into the pool for execution and it will return a Future object. By doing this you will have references to all subscriber threads.
In order to stop particular thread just use futureObj.cancel(true). This will interrupt the running thread, throwing an InterruptedException. The subscriber thread should be coded such way it will stop processing in the case of this exception (for example Thread.sleep(millis) with wrapper try / catch block for the whole method).
You cand find more information on the official API:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

Die you threadpoolexecutor

I have a java.util.concurrent.Execution service - a single threaded thread pool executor. I submit certain tasks to it. If the task throws an unchecked exception the thread dies but the service ensures that a new thread is spawned and subsequent tasks are performed in that. However I do not want this feature and still want to use a threadPoolExecutor. i.e. I want the service to shutDownNow() if the task throws an unchecked exception.
What is the best way to achieve this? Would using a custom thread factory which restricts the number of threads spawned make good sense?
You can create a ThreadPoolExecutor subclass and override the afterExecute method. The method has a throwable parameter that will be non-null if there was an exception.
You could wrap your threadPoolExecutor in an ExecutorCompletionService. Then continually take() from it, retrieving Futures. If future.get() throws an Exception, call threadpoolexecutor.shutdown().

Categories

Resources