Interrupt a sleeping thread - java

Trying to interrupt a running thread, in this example, t1, which is executed by a thread in a thread pool.
t2 is the one that sends the interrupt.
I'm unable to stop the running t1, t1 does not get InterruptedException.
What am I missing?
Executor exec1 = Executors.newFixedThreadPool(1);
// task to be interrupted
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("starting uninterruptible task 1");
Thread.sleep(4000);
System.out.println("stopping uninterruptible task 1");
} catch (InterruptedException e) {
assertFalse("This line should never be reached.", true);
e.printStackTrace();
}
}
};
final Thread t1 = new Thread(runnable);
// task to send interrupt
Runnable runnable2 = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
t1.interrupt();
System.out.println("task 2 - Trying to stop task 1");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(runnable2);
exec1.execute(t1);
t2.start();
t2.join();

Seems like you misunderstand threads and Executors. You create two threads object for two runnables, but start only one of them (t2), t1 you pass to Executor to run inside it. But executor does not need Thread to be supplied -- it just need Runnable implementation. Executor itself is a thread pool (usually, but it's not required), and it just creates (and pool) threads inside it. It sees you thread just as simple Runnable (which is Thread implements). So you actualy send interrupt to the thread which was never started.
If you really want to make your code works, you should remove Executor, and just start both threads explicitly.

Your mistake is that you're trying to execute a Thread on a ThreadPool.
This appears to work, because Thread happens to implement Runnable, but because the thread is only being used as a Runnable and is not started as a Thread, calling methods like #interrupt() won't have the desired effect.
If you still need to use a thread pool, you should instead look into using a class like FutureTask. Wrap your Runnable in a FutureTask, and then submit the task to a thread pool. Then, when you want to interrupt the task, call futureTask.cancel(true).

The problem is that you can never really know which thread would be used by the Executor to run your task.
Even though you have submitted a Thread object, The Executor will use the thread created by the fixed thread pool. Thus the thread with reference t1 is not the thread in which your task is going to be executed. so calling t1.interrupt() is not going to do anything.
To properly way to do this is to use an ExecutorService and use the submit() to submit a Runnable/Callable object. This will return a Future which exposes a cancel() method which can be used to cancel the task.

Calling Thread.interrupt does not necessarily throw an InterruptedException. It may just set the interrupted state of the thread, which can be polled by Thread.interrupted() or Thread.isInterrupted.
See http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#interrupt() for more details.

To interrupt the executor thread ,
final ExecutorService exec1 = Executors.newFixedThreadPool(1);
final Future<?> f = exec1.submit(runnable);
...
f.cancel(true);

Related

Will the Thread.currentThread() method always return the same object troughout the Runnable's lifetime?

I've been using Thread#currentThread() in my Runnable#run() method to get a reference to the currently executing thread. Since the Runnable can be running for a while with multiple similar copies in parallel in an Executor, will it always return the same Thread object or can that change over the course of the the lifetime of the Runnable?
So basically, will I run into issues when I run this kind of Runnable for a while?
class MyRunnable implements Runnable {
#Override
public void run() {
Thread current = Thread.currentThread();
while(!current.isInterrupted()) {
try {
// some processing that can take a while...
} catch(InterruptedException e) {
// some cleanup
current.interrupt();
}
}
// goodbye
}
}
You are asking the wrong question. As long as code is executed within the same thread, the expression Thread.currentThread() will evaluate to the same object, which represents that thread.
But this has nothing to do with the “Runnable’s lifetime”. The Runnable, or more precisely the instance of the class implementing runnable, is an ordinary object that can be used independently of threads. Most notably, multiple threads may execute the run() method of the same object:
class MyRunnable implements Runnable {
#Override
public void run() {
Thread current = Thread.currentThread();
System.out.println(current);
}
}
MyRunnable r = new MyRunnable();
new Thread(r).start();
new Thread(r).start();
new Thread(r).start();
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-2,5,main]
This, however doesn’t imply that it was wrong to assume to get the same Thread instance for a particular execution.
To built on your example code:
class MyRunnable implements Runnable {
#Override
public void run() {
Thread current = Thread.currentThread();
while(!current.isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
current.interrupt();
}
}
System.out.println(current+" has been interrupted, exiting");
}
}
MyRunnable r = new MyRunnable();
Thread[] threads = { new Thread(r), new Thread(r), new Thread(r) };
for(Thread t: threads) t.start();
for(Thread t: threads) try {
Thread.sleep(400);
System.out.println("going to interrupt "+t);
t.interrupt();
t.join();
}
catch (InterruptedException ex) {
throw new AssertionError(ex);
}
will correctly print:
going to interrupt Thread[Thread-0,5,main]
Thread[Thread-0,5,main] has been interrupted, exiting
going to interrupt Thread[Thread-1,5,main]
Thread[Thread-1,5,main] has been interrupted, exiting
going to interrupt Thread[Thread-2,5,main]
Thread[Thread-2,5,main] has been interrupted, exiting
So Thread.currentThread() will return the same object throughout the threads lifetime (when being called from that thread), not the runnable`s lifetime, but that’s precisely what you want. You could also use
class MyRunnable implements Runnable {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
System.out.println(Thread.currentThread()+" has been interrupted, exiting");
}
}
to the same effect. But keep in mind that the first example works because the thread has been stored in a local variable. If you are going to store the thread into a field of the object, you have to ensure that the object is not used by multiple threads concurrently (as you always have to take care when using shared mutable state by multiple threads).
Each Thread has its own ID and you can call method getId() to obtain it. Then you can determine if it is the same Thread.
From the javadoc of the method getId()
Returns the identifier of this Thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime. When a thread is terminated, this thread ID may be reused.
Will the Thread.currentThread() method always return the same object troughout the Runnable's lifetime?
Yes, Thread.currentThread() will return the same reference anytime you invoke it in a particular thread; however not throughout the Runnable's lifetime, but rather throughout the lifetime of the current thread.
Runnable type exists independent from the Thread, and you can use it without the latter. If you, for example, store the Runnable instance reference in some variable, and you will pass the same instance to the Thread, exiting the runner thread will not cause the deallocation of that instance of the Runnable.
You should note, that once the thread kicks off with .start()(after which, JVM internally calls .run()), it is illegal to restart the thread after it completes execution. Generally, it is never legal to start the same thread more than once.
So, every time you call Thread.currentThread(), you will obtain the reference to the currently executing thread object (reference to the thread, in which, this method is invoked).

is it possible to start a thread by calling run() inside a run()method?

I know that run method should not be called to start a new thread execution, but i was referring this article where they have called runnable.run(); inside another run method and it seems to be implying that it starts a new thread or its not at all creating threads, it just creates a new thread and runs all runnable in the same thread i.e task by task?
here is the code that article refers about.
public class ThreadPool {
private BlockingQueue taskQueue = null;
private List<PoolThread> threads = new ArrayList<PoolThread>();
private boolean isStopped = false;
public ThreadPool(int noOfThreads, int maxNoOfTasks){
taskQueue = new BlockingQueue(maxNoOfTasks);
for(int i=0; i<noOfThreads; i++){
threads.add(new PoolThread(taskQueue));
}
for(PoolThread thread : threads){
thread.start();
}
}
public synchronized void execute(Runnable task) throws Exception{
if(this.isStopped) throw
new IllegalStateException("ThreadPool is stopped");
this.taskQueue.enqueue(task);
}
public synchronized void stop(){
this.isStopped = true;
for(PoolThread thread : threads){
thread.doStop();
}
}
}
and
public class PoolThread extends Thread {
private BlockingQueue taskQueue = null;
private boolean isStopped = false;
public PoolThread(BlockingQueue queue){
taskQueue = queue;
}
public void run(){
while(!isStopped()){
try{
Runnable runnable = (Runnable) taskQueue.dequeue();
runnable.run();
} catch(Exception e){
//log or otherwise report exception,
//but keep pool thread alive.
}
}
}
public synchronized void doStop(){
isStopped = true;
this.interrupt(); //break pool thread out of dequeue() call.
}
public synchronized boolean isStopped(){
return isStopped;
}
}
questions:
Why thread.start(); is called inside constructor?
How do i enque my task if thread.start(); is called even before
calling this.taskQueue.enqueue(task);
To understand all these please post a driver class for this example
with maxNoOfTasks=10 and noOfThreads=3.and output for
the same would be much appreciated.
Does Runnable.run() inside run method start a new thread ?
thanks
i was referring this article where they have called runnable.run(); inside another run method and it seems to be implying that it starts a new thread.
Looking at the code, I don't see that implication at all.
It's not starting a new thread. It's running the next Runnable from a queue on the current pool thread.
I know that run method should not be called to start a new thread execution...
Not should not, cannot. :-) Calling run just calls run, on the current thread, just like any other method call.
Why thread.start(); is called inside constructor?
To start the thread that was just created with new PoolThread(taskQueue).
How do i enque my task if thread.start(); is called even before calling this.taskQueue.enqueue(task);
You pass it into execute. It gets added to the queue of things to do (taskQueue). One of the PoolThreads that ThreadPool created will pick it up when it's next free.
To understand all these please post a driver class for this example with maxNoOfTasks=10 and noOfThreads=3.and output for the same would be much appreciated.
I don't know what you mean by a driver class, but I think answering the questions is sufficient.
Does Runnable.run() inside run method start a new thread ?
No.
So to understand what this does, say you create a ThreadPool with 5 threads. The ThreadPool constructor creates and starts five PoolThread threads immediately. Those threads constantly check taskQueue to see if there's anything to do and, if so, they do it.
Initially, of course, taskQueue is always empty so the threads are busy-waiting, constantly spinning checking for something in taskQueue. (This isn't really ideal, it burns CPU for no good reason. It would be better to suspend threads when there's nothing to do, but that's starting to get pretty far from the actual question.)
Then, at some point, you call execute and pass in a task. That adds it to the taskQueue. The next time one of the five threads checks for something in taskQueue, it finds it, and runs it on that thread (not a new one).
4. Does Runnable.run() inside run method start a new thread ?
No, it will not start a new thread, It is not possible to start a new thread by calling run() method because JVM will not create a new thread until you call the start method.
If you call the run() method directly than it will be called on the same thread. JVM will not create separate thread for execution, it will execute on same thread.
On any thread instance if you call start() method it will create a new thread but if you call start() method second time on same instance, it will throw java.lang.IllegalStateException, because the thread is already started and you cannot restart it again.
You can only pause a thread in Java. Once it died it's gone.
I think this could be the reason to call like this.
Runnable runnable = (Runnable) taskQueue.dequeue();
runnable.run();
Why thread.start(); is called inside constructor?
starts the threads in pool constructor.
the threads are already running.
Runnable runnable = (Runnable) taskQueue.dequeue();
blocks the running threads
taskQueue.enque() puts new object of type Runnable to the queue and any blocked thread takes this Runnable and executes it. All the threads are started when the pool is created and in those threads are Runnable simply executed.

Calling wait() after posting a runnable to UI thread until completion

I'm actually in need of waiting for the ui thread to execute a runnable before my application thread can continue. Is the wait()/notify() way a proper way to do it or is there something better for this? What I'm actually doing looks like this:
public void showVideoView() {
try {
final AtomicBoolean done = new AtomicBoolean(false);
final Runnable task = new Runnable() {
#Override
public void run() {
synchronized(this) {
mStartupCurtain.setVisibility(View.GONE);
mVideoView.setVisibility(View.VISIBLE);
mWebView.loadUrl("about:blank");
mWebView.setVisibility(View.GONE);
done.set(true);
notify();
}
}
};
mUiHandler.post(task);
synchronized(task) {
while(!done.get()) {
task.wait();
}
Log.d(TAG, "showVideoView done!");
}
} catch (InterruptedException e) {
Log.e(TAG, "Thread got interrupted while waiting for posted runnable to finish its task");
}
}
Also when I do this I have to be sure that the thread is not the one of the UI, which happens when I start calling methods from a listener method coming from an interface like MediaPlayer.OnCompletionListener.
What do you think?
Looks fine to me.
The "done" variable could be a regular Boolean instead of AtomicBoolean since you definitively get/set it's value within the lock. I like that you check the value of "done" prior to calling wait - since it is quite possible the task will have been completed before you ever enter the lock in the worker thread. If you had not done that, the wait() call would go indefinitely since the notify() had already happened.
There is one edge case to consider that may or may not be applicable to your design. What happens if the UI thread is attempting to exit (i.e. app exit) when the worker thread is still stuck waiting for the task to complete? Another variation is when the worker thread is waiting on the task to complete, but the UI thread is waiting on the worker thread to exit. The latter could be solved with another Boolean variable by which the UI thread signals the worker thread to exit. These issues may or may not be relevant - depending on how the UI is managing the thread to begin with.
Use AsyncTask!
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
http://developer.android.com/reference/android/os/AsyncTask.html
Function:
public static void postOnUI(Runnable runnable,boolean wait) {
if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
// Is on UI thread.
runnable.run();
return;
}
Handler uiHandler = new Handler(Looper.getMainLooper());
AtomicBoolean done = new AtomicBoolean(false);
uiHandler.post(() -> {
runnable.run();
done.set(true);
});
if (wait) {
while (!done.get()) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
}
}
}
}
Usage Example:
Utils.postOnUI(headerView::updateUI,true);

Stop a runnable in a separate Thread

Hey there i currently have a problem with my android app. I´m starting an extra thread via
implementing the Excecutor Interface:
class Flasher implements Executor {
Thread t;
public void execute(Runnable r) {
t = new Thread(r){
};
t.start();
}
}
I start my Runnable like this:
flasherThread.execute(flashRunnable);
but how can i stop it?
Ok, this is just the very basic threading 101, but let there be another example:
Old-school threading:
class MyTask implements Runnable {
public volatile boolean doTerminate;
public void run() {
while ( ! doTerminate ) {
// do some work, like:
on();
Thread.sleep(1000);
off();
Thread.sleep(1000);
}
}
}
then
MyTask task = new MyTask();
Thread thread = new Thread( task );
thread.start();
// let task run for a while...
task.doTerminate = true;
// wait for task/thread to terminate:
thread.join();
// task and thread finished executing
Edit:
Just stumbled upon this very informative Article about how to stop threads.
Not sure that implementing Executor is a good idea. I would rather use one of the executors Java provides. They allow you to control your Runnable instance via Future interface:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(flashRunnable);
...
future.cancel(true);
Also make sure you free resources that ExecutorService is consuming by calling executorService.shutdown() when your program does not need asynchronous execution anymore.
Instead of implementing your own Executor, you should look at ExecutorService. ExecutorService has a shutdown method which:
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
I would suggest to use the ExecutorService, along with the Furure object, which gives you control over the thread that is being created by the executor. Like the following example
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(runnabale);
try {
future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
Log.warn("Time out expired");
} finally {
if(!future.isDone()&&(!future.isCancelled()))
future.cancel(true);
executor.shutdownNow();
}
This code says that the runnable will be forced to terminate after 2 seconds. Of course, you can handle your Future ojbect as you wish and terminate it according to your requierements

ExecutorService, how to know when all threads finished without blocking the main thread?

I have a multithreaded implementation where i create an ExecutorService and submit tasks to be executed, i want to know when all the threads is submited have finished without blocking the main thread and the UI. I've tried ExecutorService.awaitTermination() but it blocks the main thread and the UI. I've searched alot but i can't seem to find an elegant way of doing this. I'm currently thinking about creating another thread that counts the amount of threads finished and launches an event when they all finished, but that doesn't to be a good approach and i wanted a better solution!
Use a SwingWorker to shutdown the thread pool and call awaitTermination(). This will prevent the UI from blocking and call done() from the Event Dispatch Thread on your SwingWorker implementation which you can use to trigger the whatever UI changes you need.
If you desire to keep track of the threads running via a UI update you can use the the worker thread to monitor this in a loop and call publish() with arguments which then get passed to your implementation of process() on the EDT.
Why not use a CountDownLatch and then notify the main thread when the latch has been completed.
isTerminated() will do
note however that both awaitTermination and isTerminated will only give you a meaningful result after you have called shutdown
You can maintain a separate thread to track when the executor service instance shuts down:
final ExecutorService execSvc = ...;
execSvc.submit(task1);
...
execSvc.submit(taskN);
// important to request the exec service to shut down :)
execSvc.shutdown();
new Thread(new Runnable() {
public void run() {
while (!execSvc.isTerminated()) {
try {
execSvc.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// ignore exception
}
}
System.out.println("ExecSvc.run: exec service has terminated!");
// possibly submit a task using SwingUtilities.invokeLater() to update the UI
}
}).start();
Using CountDownLatch
CountDownLatch latch = new CountDownLatch(totalNumberOfTasks);
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
try {
latch.await();
} catch (InterruptedException E) {
// handle
}
and within your task (enclose in try / finally)
latch.countDown();
Or on ExecutorService you call shutdown() and then awaitTermination()
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
Also have a look at THIS answer

Categories

Resources