In this code
public class NoncancelableTask {
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
interface Task {
}
}
What if queue is already empty? Code will swallow first exception, then retry - and wait forever?
I thought main idea of interruption is cancellation of task if it stuck on some blocking method like Thread.sleep, BlockingQueue.take(), etc.
There is similar question What is the point of restoring the interrupted status in JCIP listing 7.7? , but I don't have enough reputation to post a comment
The point of interruption is not cancellation, the two should be separate when you are thinking about interruption logic. Interruption can be used for cancellation, but as in the sample above, it can also be ignored as well.
It could be that the task returned by getNextTask(...) is so important that the thread cannot afford to exit when interrupted. Therefore, the thread will remain blocked until a task is available in the queue, unless the program completely dies or encounters a catastrophic error.
Again, this is not waiting indefinitely, only until there is a task available. What makes this sample important is that it contains a boolean check when returning, which will pass the interruption to the calling thread. That way, when the thread finally unblocks, an interruption can be checked for it to exit if necessary.
queue.take() will wait until there is something to take. Nothing is throwing an InterruptedExcpetion so the catch block won't execute. You will remain in the try block until something is added to the que or you throw an interupted exception.
Thread.currentThread().interrupt(), unless I am wrong, will not do much, because your code is single threaded right now, and that single thread is already out of the try block if it is in the finally block.
Here is an example of how to use interrupt:
public class StoppingThreads implements Runnable
{
public static void main(String[] args)
{
Thread t0 = new Thread(new StoppingThreads());
t0.start();
Thread t1= new Thread(new StoppingThreads());
t1.start();
Thread t2 = new Thread(new StoppingThreads());
t2.start();
Thread t3 = new Thread(new StoppingThreads());
t3.start();
Thread t4 = new Thread(new StoppingThreads());
t4.start();
System.out.println("All threads started");
t0.interrupt();
t1.interrupt();
}
#Override
public void run()
{
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
System.out.println(Thread.currentThread().getName() + " Finished");
}
}
Related
Recently I am working on a piece of code involving synchronization and struggling on how to test it. To get into the problem, we can consider we are writing a unit test for a CountDownLatch:
CountDownLatch l = new CountDownLatch(1);
new Thread() {
#Override
void run() {
l.await();
System.out.println("good!");
}
}.start();
Thread.sleep(1000); // wait for thread to run
if (the thread is alive)
l.countDown();
else
System.out.println("bad!");
So the problem is, there is no guarantee that the sleep for 1 second would be enough in all cases in all machines. So my goal is to eliminate this type of sleeping code to expect a certain state when testing synchronization, but soon realize it starts to become halting problem.
My current solution would be to query the state of the thread:
Thread t = ...
t.start();
if (t.getState() == Thread.State.WAITING) {
l.countDown();
assert(t.getState() == Thread.State.RUNNABLE); // or running or terminated
}
my questions are:
would that work? i.e. would the state of the thread will be toggled atomically at the moment, in this case, a count down latch reach a wakeup condition?(the doc says nothing about the change timing of the state)
do you have better suggestions?
Looking into your example I have a feeling that you're using countdown latch upside-down. Why can't you do something like that:
#Test
public void testThreads() throws Exception {
CountDownLatch l = new CountDownLatch(1);
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Parallel thread is doing something.");
try {
// instead of this sleep you put your logic that you want to be executed.
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
l.countDown();
}
}).start();
System.out.println("Main thread is waiting for parallel thread");
l.await();
System.out.println("Done.");
}
Please, correct me if I misunderstand your problem.
But generally speaking, I agree with one of the comments below your post that you should probably not test multithreading with unit tests.
final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future<?> future = executor.submit(myRunnable);
executor.shutdown();
if(executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("task completed");
}else{
System.out.println("Executor is shutdown now");
}
//MyRunnable method is defined as task which I want to execute in a different thread.
Here is run method of executor class:
public void run() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
Here it is waiting for 20 second but when i run the code it throws an exception:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
I am not able to close the concurrent thread ruining in Java Executor class. Here is my Code flow:
Created a new Thread with Java executor class to run some task i.e written in MyRunnable
executor wait for 10 second to complete the tasks.
If the task has completed then runnable thread also got terminated.
If the task is not completed within 10 second then executor class should terminate the thread.
Everything works fine except the termination of tasks in the last scenario. How should I do it?
The shutDown() method simply prevents additional tasks from being scheduled. Instead, you could call shutDownNow() and check for thread interruption in your Runnable.
// in your Runnable...
if (Thread.interrupted()) {
// Executor has probably asked us to stop
}
An example, based on your code, might be:
final ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
public void run() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
System.out.println("Interrupted, so exiting.");
}
}
});
if (executor.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("task completed");
} else {
System.out.println("Forcing shutdown...");
executor.shutdownNow();
}
It is generally a bad idea to terminate a running thread from the outside, because you don't know the state the thread is currently in. It's possible that it needs to do some cleanups, and it won't be able to do that when you forcefully shut it down. That's why all methods of Thread which do that are marked as deprecated.
It's much better to use one of the many techniques which are available for interprocess communication to signal the procedure running in the thread itself that it has to abort its work and exit normally. One way to do this is to add an abort() method to your runnable, which raises a flag declared as volatile. The inner loop of your Runnable checks that flag and exits (in a controlled fashion) when that flag is raised.
I am getting IllegalThreadStateException exception when using following code:
I have already started this thread once(by using thread.start()) and again trying to start it at another place, so used following code:
thread.interrupt();
thread.start();
But thread.start() is throwing IllegalThreadStateException.
What should I use to solve it?
Thread objects are only meant to be started once. If you need to stop/interrupt a Thread, and then want to start it again, you should create a new instance, and call start() on it:
thread.interrupt(); // if you need to make sure thread's run() method stops ASAP
thread = new MyThreadSubclass();
thread.start();
From the API docs
IllegalThreadStateException - if the thread was already started.
I know it's not 100% clear that you can't call start() again, even if you previously called interrupt(), but that's the way it works.
If you look at the API docs for standard Java, this issue is more clear.
In addition to Nate's answer.
AnkitRox states in his comment:
Thanks Nate. I was also trying your method. But the problem occurred at that time was, it was start a new thread for the new instance and previous thread was also working.
So it looks like the problem is "the thread is still running even if I called interrupt on it". Consider this sample (it is ugly, but enough to show the main idea):
final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
for (int i = 0; i < 100000000; i++); // simulate some action
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
Note, the thread continues to run even after interrupt() has been called. The produced output is:
hi, interrupted = false
hi, interrupted = true
hi, interrupted = true
hi, interrupted = true
...
hi, interrupted = true
Actually the programm never stops unless closed forcefully. So what then the interrupt() does? It just sets the interrupted flag to true. After interrupt() has been called the Thread.currentThread().isInterrupted() starts to return false. And that's all.
Another case is if interrupt() is called while the thread is blocked in an invocation of one of the methods that throw InterruptedException, then that method will return throwing the InterruptedException. And if thread's code just "eats" that exception, then the thread will still continue running, consider a sample:
final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("got InterruptedException");
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
Note, the thread continues to run even after interrupt() has been called. The produced output is:
hi, interrupted = false
got InterruptedException
hi, interrupted = false
hi, interrupted = false
...
hi, interrupted = false
Note, this time interrupted = false even after interrupt() has been called. This is because whenever InterruptedException is caught, the interrupted flag is reset to false.
In Java stopping a thread is cooperative mechanism. Meaning it can not be done without cooperation from the thread itself. Here is the fixed version of the above sample:
final Thread t = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("we've been interrupted");
// restore the interrupted flag
Thread.currentThread().interrupt();
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
So the correct approach should be to periodically check the interrupted flag. And if interrupted status is detected then just return ASAP. Another common option is not to use Thread.interrupt() at all, but some custom boolean instead.
I want to interrupt a thread, but invoking interrupt() doesn't seem to work. Below is the sample code:
public class BasicThreadrRunner {
public static void main(String[] args) {
Thread t1 = new Thread(new Basic(), "thread1");
t1.start();
Thread t3 = new Thread(new Basic(), "thread3");
Thread t4 = new Thread(new Basic(), "thread4");
t3.start();
t1.interrupt();
t4.start();
}
}
class Basic implements Runnable{
public void run(){
while(true) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.err.println("thread: " + Thread.currentThread().getName());
//e.printStackTrace();
}
}
}
}
but the output looks like thread 1 is still running. Can anyone explain this as well as how interrupt() works? Thanks!
The thread is still running simply because you catch InterruptedException and keep running. interrupt() primarily sets a flag in the Thread object, which you can check with isInterrupted(). It also causes some methods -- sleep(), join Object.wait(), in particular -- to return immediately by throwing an InterruptedException. It also causes some I/O operations to immediately terminate. If you're seeing the printouts from your catch block, then you can see that interrupt() is working.
As others have said, you catch the interrupt, but do nothing with it. What you need to do is propagate the interrupt using logic such as,
while(!Thread.currentThread().isInterrupted()){
try{
// do stuff
}catch(InterruptedException e){
Thread.currentThread().interrupt(); // propagate interrupt
}
}
Using looping logic, such as while(true) is just lazy coding. Instead, poll the thread's interrupted flag in order to determine termination via interruption.
++1, in addition to other answers. I believe the misconception about this was that it seemed the try/catch block finished its job after the Thread.sleep(1000); call i.e. try to sleep for 1000ms, catch anything that might interrupt my sleep attempt.
What is happening actually is that the try/catch block is still very much active while sleeping i.e. try to sleep for 1000ms, catch anything that might interrupt during my sleep
Hence the reason why the exception is being caught immediately (and afterwards) since the thread barely just started its sleep.
Started several worker threads , need to notify them to stop. Since some of the threads will sleep for a while before next round of working, need a way which can notify them even when they are sleeping.
If it was Windows programming I could use Event and wait functions. In Java I am doing this by using a CountDownLatch object which count is 1. It works but don't feel elegant, especially I have to check the count value to see if need to exit :
run(){
while(countDownLatch.count()>0){
//working
// ...
countDownLatch.wait(60,TimeUnit.SECONDS);
}
}
Semaphore is another choice, but also don't feel very right. I am wondering is there any better way to do this? Thank you.
Best approach is to interrupt() the worker thread.
Thread t = new Thread(new Runnable(){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
//do stuff
try{
Thread.sleep(TIME_TO_SLEEP);
}catch(InterruptedException e){
Thread.currentThread().interrupt(); //propagate interrupt
}
}
}
});
t.start();
And as long as you have a reference to t, all that is required to "stop" t is to invoke t.interrupt().
Use the builtin thread interruption framework. To stop a worker thread call workerThread.interrupt() this will cause certain methods (like Thread.sleep()) to throw an interrupted exception. If your threads don't call interruptable methods then you need to check the interrupted status.
In the worker thread:
run() {
try {
while(true) {
//do some work
Thread.sleep(60000);
}
}
catch(InterruptedException e) {
//told to stop working
}
}
Good way is to interrupt() threads, and inside thread make cycle like
try {
while (!Thread.interrupted()) {
...
}
} catch (InterruptedException e) {
// if interrupted in sleep
}
Keep in mind both cases when do interrupt:
if you sleep or wait then InterruptedException will be thrown;
in other cases interrupted flag will be set for the thread which you have to check yourself.
To have a pool of threads I would use the ExecutorService or a ScheduledExecutorService for delayed/periodic tasks.
When you want the workers to stop you can use
executorService.shutdown();
The other best approach would be to use interrupt( ) method.
E.g Here's how a thread uses this information to determine whether or not it should terminate :
public class TestAgain extends Thread {
// ...
// ...
public void run( ) {
while (!isInterrupted( )) {
// ...
}
}
}