I have a short version of the question:
I start a thread like that: counter.start();, where counter is a thread.
At the point when I want to stop the thread I do that: counter.interrupt()
In my thread I periodically do this check: Thread.interrupted(). If it gives true I return from the thread and, as a consequence, it stops.
And here are some details, if needed:
If you need more details, they are here. From the invent dispatch thread I start a counter thread in this way:
public static void start() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showGUI();
counter.start();
}
});
}
where the thread is defined like that:
public static Thread counter = new Thread() {
public void run() {
for (int i=4; i>0; i=i-1) {
updateGUI(i,label);
try {Thread.sleep(1000);} catch(InterruptedException e) {};
}
// The time for the partner selection is over.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.remove(partnerSelectionPanel);
frame.add(selectionFinishedPanel);
frame.invalidate();
frame.validate();
}
});
}
};
The thread performs countdown in the "first" window (it shows home much time left). If time limit is over, the thread close the "first" window and generate a new one. I want to modify my thread in the following way:
public static Thread counter = new Thread() {
public void run() {
for (int i=4; i>0; i=i-1) {
if (!Thread.interrupted()) {
updateGUI(i,label);
} else {
return;
}
try {Thread.sleep(1000);} catch(InterruptedException e) {};
}
// The time for the partner selection is over.
if (!Thread.interrupted()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.remove(partnerSelectionPanel);
frame.add(selectionFinishedPanel);
frame.invalidate();
frame.validate();
}
});
} else {
return;
}
}
};
ADDED:
Because of some reasons it does not work. I have a method which interrupts the thread:
public static void partnerSelected() {
System.out.println("The button is pressed!!!!");
counter.interrupt();
}
This method is activated when a button is pressed. When I press the button I see the corresponding output in the terminal (so this method is activated and it does something). But because of some reasons it does not interrupt the thread. Here is the code for the thread:
public static Thread counter = new Thread() {
public void run() {
for (int i=40; i>0; i=i-1) {
if (Thread.interrupted()) {
System.out.println("Helloo!!!!!!!!!!!!!!!");
return;
}
updateGUI(i,label);
try {Thread.sleep(1000);} catch(InterruptedException e) {};
}
// The time for the partner selection is over.
if (Thread.interrupted()) {
System.out.println("Helloo!!!!!!!!!!!!!!!");
return;
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.remove(partnerSelectionPanel);
frame.add(selectionFinishedPanel);
frame.invalidate();
frame.validate();
}
});
}
};
P.S. I do not see "Hello!!!!!!!!!!!!!" in the terminal...
Pretty close to the right idea. However, in your catch (InterruptedException) you should have:
Thread.currentThread().interrupt();
so that the interrupted status goes on again, and doesn't do the stuff in the second block.
Edit to make my point clearer (because the OP's edit seems to have missed my initial point :-P): you should write your code like this:
try {
for (int = 40; i > 0; --i) {
updateGUI(i, label);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // <-- THIS LINE IS IMPORTANT
}
Second edit to explain what interruption does. :-)
When you call thread.interrupt(), that thread's interrupted flag is set. That flag doesn't do anything on its own; it's just a variable. The reason for this is because interruption supports something called "cooperative thread management", where the thread's running code decides what to do when interrupted (rather than being forced to quit on the spot).
Some functions built into the JDK, like Thread.sleep, or Object.wait, or Lock.lockInterruptibly, will check the flag, and if it's set, then it'll throw an InterruptedException after clearing the flag.
So, if you're calling one of those functions, you don't need to manually check the interrupted flag. But if you're not, e.g., if you're doing intensive processing instead of waiting for something, then you should periodically check the flag.
There are two ways to check the flag:
interrupted()
isInterrupted()
The first one clears the interrupted flag; the second one doesn't. You have to decide which version is "more correct" for your application logic.
Yes it is the way to go
It's considered a better way (link) to use separate volatile variable (boolean isStopped) for this purpose.
Assume that interrupted() method changes value from true to false if your thread was interrupted, i.e.:
System.out.println (Thread.interrupted()); //true
System.out.println (Thread.interrupted()); //false
The alternative is isInterrupted() method.
Check out this article from the JavaSpecialists newsletter, which covers how to interrupt() threads and manage this properly.
Edit/Preamble
I'd like to edit and note that I've learned a lesson here today. There's no reason to implement a boolean as I explain in the following two paragraphs; the interrupt mechanism does that for me. For some reason I had assumed that "interrupt" stops the thread dead in its tracks (I don't know what I thought isInterrupted() did then!).
So, here is an example of what not to do. Keep on using your interrupt technique!
Original answer
I tend to avoid interrupt, but especially to stop a thread. In your case, you're trying to use interrupt() as an alternative to stop(), which has been deprecated for good reason. All you need to do is declare a boolean which represents whether the thread should stop counting, and have the thread continuously check that boolean value. Then, when the parent thread is ready for the counter to stop, it should set the boolean to true (stop), which will cause the counter thread to stop as soon as it checks the value again.
In your Counter thread's anonymous class definition, add public volatile boolean shouldStop;. At the beginning of run(), set shouldStop = false;. Then replace all Thread.interrupted() with shouldStop (in your if statements). Finally, instead of calling counter.interrupt(), just say counter.shouldStop = true;. You can additionally call counter.join() right after setting shouldStop=true if you want to ensure that counter has stopped before continuing.
Related
I have a program with multiple threads operating on a single instance of a class. Sometimes one of these threads will get interrupted. I have in the method header "throws InterruptedException" so it does that part correctly. The problem is that when a thread gets interrupted, the fields don't get reset, so the next thread that comes in gets all messed up.
How do I check if a thread is interrupted so that I can reset the variables for the next thread that comes in? I'm not sure where to address this in my code. I have tried something like:
if(Thread.currentThread().isInterrupted()) {
//reset variables here
}
or:
if(Thread.interrupted()) {
//reset variables here
}
Can anyone help me out? Thank you in advance!
You can encase your whole thing in a try-catch block:
try {
//Code here
} catch (InterruptedException e) {
//Reset variables here
}
You can check (or handle) if a thread has been interrupted in two ways:
You receive an InterruptedException when performing operations that might keep your thread waiting for an undefined amount of time, like a sleep or a wait invocation.
public class MyRunnable implements Runnable {
public void run(){
try {
while(true){
someOperation();
TimeUnit.SECONDS.sleep(2);
}
} catch(InterruptedException ex) {
//reset variables
}
}
}
If you're performing some heavy operations, you might wanna check in specific points of your code if you've received an interruption with the methods you mentioned above.
public class MyRunnable implements Runnable {
public void run(){
while(true){
someHeavyOperation();
if (Thread.currentThread().isInterrupted()){
//reset variables
return;
}
}
}
}
Here's also a link to the Oracle Tutorials explaining Java's support to thread interruption
https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
All answers are about how to stop loop of some thread, but what if I don't have a loop but I still want to stop a thread before it executes/processes all lines?
For example I have a thread which usually runs for 7-10 seconds and then dies (terminates):
mThread = new Thread(new Runnable() {
#Override
public void run() {
// some code here
// some here
// some here
// some here
// some here
// all lines takes about 7-10 seconds
}
});
If I started a thread and after 2 or 3 seconds I need to stop it, then how to do it and don't wait 10 seconds?
If your thread is not blocked, and is actually processing stuff, then interrupting it might not help. You can code the thread to check for the interrupt flag on the current thread and then stop if it sees that the flag has been set.
This is how you check to see if the current thread has been interrupted.
Thread.currentThread().isInterrupted();
So you would have to code your thread like this...
mThread = new Thread(new Runnable() {
#Override
public void run() {
// some code here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
// all lines takes about 7-10 seconds
}
});
Then you can go ahead and interrupt the mThread and it will have an effect. Though it will still continue processing the current some here step it is on.
Explanation
The preferred way is to implement a stopping mechanism in the thread. You can also try to observe the interrupt flag. You can interrupt from outside using the Thread#interrupt method and the thread can check the flag using Thread#isInterrupted and Thread#interrupted (see documentation of Thread).
There is no way to force a thread from outside to stop without the thread actually implementing the logic by itself. There is the Thread#stop method but it is deprecated and should never be used. From its documentation:
Deprecated. This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
Solution
You could modify the thread like this:
public class MyThread implements Runnable {
private volatile boolean mShouldStop = false;
public void shutdown() {
mShouldStop = true;
}
#Override
public void run() {
// First line ...
if (mShouldStop) return;
// Second line ...
if (mShouldStop) return;
// Third line ...
if (mShouldStop) return;
}
}
So you need to periodically check the flag and then manually abort.
Usually such threads have some kind of while (true) loop. In this case it gets easier, you could do:
#Override
public void run() {
while (!mShouldStop) {
// Do something ...
}
}
Depending on your application you might interpret the interruption flag as signal for a thread shutdown. Then your code could look like
#Override
public void run() {
while (!Thread.interrupted()) {
// Do something ...
}
}
Note
The mShouldStop needs to be volatile to ensure it is updated correctly for the Thread. See the tutorial by Oracle for Atomic Access.
You interrupt the thread with mThread.interrupt(). But, for this to work, your thread needs to check the interrupt status (by sleeping). Check out this thread.
For more details, refer this thread.
You need to check the interrupt status in your thread. Something like this
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class ThreadInterruptor {
private static class Worker implements Runnable {
#Override
public void run() {
while (true) {
IntStream.range(0, Short.MAX_VALUE).forEach(i ->noop());
if (Thread.currentThread().isInterrupted()) {
System.out.println("i got interrupted");
break;
}
}
}
private void noop(){}
}
public static void main(String[] args) throws Exception{
Thread thread = new Thread(new Worker());
thread.start();
TimeUnit.SECONDS.sleep(5);
thread.interrupt();
}
}
I've seen a lot of example for wait and notify, but still I have a problem.
public class Main(){
public static void main(String args[]) throws Exception {
MyThread s = new MyThread();
s.start();
}
}
class MyThread extends Thread {
public void run() {
k();
}
public synchronized void k() {
System.out.println("before wait");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("do something after wait");
}
public synchronized void m() {
for (int i=0;i<6;i++)
System.out.println(i);
notify();
}
}
The only output I get when run the program is: "before wait".
The thread you create in main invokes MyThread#k() which goes into a wait. At that point, that thread will do nothing else until it is awakened or interrupted. But the only place in your code where it could possibly be awakened is the notify in MyThread#m(). Since nothing in your program calls that method, the thread can never be awoken.
What you probably want is to add a call to s.m() right after s.start() in your main program. That way your main thread will execute the notify that's needed to wake up your thread.
Unfortunately, that's very unlikely to work. The problem is that s.start() causes your created thread to become ready to run, but it doesn't necessarily run immediately. It could well happen that your call to s.m() will complete before the created thread does anything. And then you'll still have exactly the same result as before, except that you'll see the integers 0..6 printed out before before wait. The notify will do nothing, because the child thread has not yet performed its wait. (And by the way, since both MyThread#k() and MyThread#m() are both synchronized, increasing your loop limit in MyThread#m() won't change a thing... the child thread won't be able to enter MyThread#k() while MyThread#m() is running. You could improve that by putting the notify in a sycnchronized block rather than making all of MyThread#m() synchronized.)
You can try to get around this by adding Thread.sleep(1000) before s.m() in your main program. That will almost certainly work because your main thread will yield execution, giving your JVM the opportunity to schedule the child thread for some useful work. By the time the main thread wakes out of its sleep and performs its s.m() call, the child will probably have executed its wait and you will then see your do something after wait message.
But that's still pretty crummy, because it still depends on scheduling events that you don't really have any control over. There's still no guarantee that the wait will happen before the notify.
This is why when using wait/notify you should generally arrange for there to be some sort of reliable test as to whether whatever you're waiting to be done has actually occurred. This should be a condition that, once it turns turns true, will remain true at least until the test has been subsequently performed. Then your typical wait loop looks something like this:
while (!isDone()) {
synchronized(monitorObject) {
try {
monitorObject.wait();
} catch (InterruptedException e) {
}
}
}
Putting the whole thing in a loop takes care of premature waking, e.g. due to InterruptedException.
If the required work has already occurred by the time this code is executed, no wait occurs, and the notify executed by the code that did the work was a no-op. Otherwise, this code waits, and the code completing the work will eventually do a notify which will wake this code up as required. Of course, it's critical that, at the time the notify is performed, the wait condition (isDone() above) be true and remain true at least until tested.
Here's a corrected version of your code that incorporates a proper wait loop. If you comment out the Thread.sleep() call, you will likely not see the waiting message, because the work will complete before the wait loop even starts. With the sleep included, you'll probably see the waiting message. But either way, the program will work properly.
public static void main(String[] argv) throws Exception {
MyThread s = new MyThread();
s.start();
Thread.sleep(1000);
s.m();
}
class MyThread extends Thread {
#Override
public void run() {
k();
}
private boolean done = false;
public void k() {
System.out.println("before wait");
while (!done) {
System.out.println("waiting");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("do something after wait");
}
public void m() {
for (int i = 0; i < 6; i++) {
System.out.println(i);
}
synchronized (this) {
done = true;
notify();
}
}
}
The problem is, that you're not calling your m method, so notify is never called, so your thread sleeps forever. You could call it in main, after the start, using s.m():
MyThread s = new MyThread();
s.start();
s.m();
Maybe you should sleep for a little time before calling the m method, as it could run sooner than k in the thread:
s.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// nothing to do
}
s.m();
Not closely related to the question, but a throws declaration in main is not very advisable, even a generated printStackTrace is better than throwing the exception away.
I'm hoping someone can help me with this. I've been searching for about a week for an answer to this issue, with no avail.
I currently have a custom thread class that implements Runnable, which I'd like to pause upon a key press. Based on my research, I've learned that the best way to go about this is by using wait() and notify(), triggered by a key that's using a key binding.
My question is, how can I get this to work? I can't seem to set up a key binding without something going wrong, and how I might implement wait() and notify() without running into a deadlock is beyond me.
wait and notify are meant to be used for synchronization. It seems to me that you wanted to use methods like Thread.suspend(), Thread.stop() and Thread.resume(), but those have been deprecated for the risk of problems with lock that they cause.
The solution is to use a helper variable that the thread will check periodically to see if it should be running, otherwise, yield(or sleep)
Why not to use suspend, stop or resume: http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Simple solutions:
How to Pause and Resume a Thread in Java from another Thread
http://www.tutorialspoint.com/java/java_thread_control.htm
Here is a simple snapshot that might get you started :
class PausableThread extends Thread {
private volatile boolean isPaused;
#Override
public void run() {
while (true /* or some other termination condition */) {
try {
waitUntilResumed();
doSomePeriodicAction();
} catch (InterruptedException e) {
// we've been interrupted. Stop
System.out.println("interrupted. Stop the work");
break;
}
}
}
public void pauseAction() {
System.out.println("paused");
isPaused = true;
}
public synchronized void resumeAction() {
System.out.println("resumed");
isPaused = false;
notifyAll();
}
// blocks current thread until it is resumed
private synchronized void waitUntilResumed() throws InterruptedException {
while (isPaused) {
wait();
}
}
private void doSomePeriodicAction() throws InterruptedException {
System.out.println("doing something");
thread.sleep(1000);
}
}
So, you start your thread somewhere new PausableThread().start();
And then in your button/keypress listeners on UI thread you call
in OnPauseKeyPress listener mPausableThread.pauseAction();,
and for OnResumeKeyPress you call mPausableThread.resumeAction();
To stop the tread altogether, just interrupt it : mPausableThread.interrupt();
Hope that helps.
I have created class by implementing runnable interface and then created many threads(nearly 10) in some other class of my project.How to stop some of those threads?
The simplest way is to interrupt() it, which will cause Thread.currentThread().isInterrupted() to return true, and may also throw an InterruptedException under certain circumstances where the Thread is waiting, for example Thread.sleep(), otherThread.join(), object.wait() etc.
Inside the run() method you would need catch that exception and/or regularly check the Thread.currentThread().isInterrupted() value and do something (for example, break out).
Note: Although Thread.interrupted() seems the same as isInterrupted(), it has a nasty side effect: Calling interrupted() clears the interrupted flag, whereas calling isInterrupted() does not.
Other non-interrupting methods involve the use of "stop" (volatile) flags that the running Thread monitors.
How to stop a thread created by implementing runnable interface?
There are many ways that you can stop a thread but all of them take specific code to do so. A typical way to stop a thread is to have a volatile boolean shutdown field that the thread checks every so often:
// set this to true to stop the thread
volatile boolean shutdown = false;
...
public void run() {
while (!shutdown) {
// continue processing
}
}
You can also interrupt the thread which causes sleep(), wait(), and some other methods to throw InterruptedException. You also should test for the thread interrupt flag with something like:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// continue processing
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// good practice
Thread.currentThread().interrupt();
return;
}
}
}
Note that that interrupting a thread with interrupt() will not necessarily cause it to throw an exception immediately. Only if you are in a method that is interruptible will the InterruptedException be thrown.
If you want to add a shutdown() method to your class which implements Runnable, you should define your own class like:
public class MyRunnable implements Runnable {
private volatile boolean shutdown;
public void run() {
while (!shutdown) {
...
}
}
public void shutdown() {
shutdown = true;
}
}
Stopping the thread in midway using Thread.stop() is not a good practice. More appropriate way is to make the thread return programmatically. Let the Runnable object use a shared variable in the run() method. Whenever you want the thread to stop, use that variable as a flag.
EDIT: Sample code
class MyThread implements Runnable{
private volatile Boolean stop = false;
public void run(){
while(!stop){
//some business logic
}
}
public Boolean getStop() {
return stop;
}
public void setStop(Boolean stop) {
this.stop = stop;
}
}
public class TestStop {
public static void main(String[] args){
MyThread myThread = new MyThread();
Thread th = new Thread(myThread);
th.start();
//Some logic goes there to decide whether to
//stop the thread or not.
//This will compell the thread to stop
myThread.setStop(true);
}
}
If you use ThreadPoolExecutor, and you use submit() method, it will give you a Future back. You can call cancel() on the returned Future to stop your Runnable task.
Stopping (Killing) a thread mid-way is not recommended. The API is actually deprecated.
However, you can get more details including workarounds here: How do you kill a Thread in Java?
Thread.currentThread().isInterrupted() is superbly working. but this
code is only pause the timer.
This code is stop and reset the thread timer.
h1 is handler name.
This code is add on inside your button click listener.
w_h =minutes w_m =milli sec i=counter
i=0;
w_h = 0;
w_m = 0;
textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
hl.removeCallbacksAndMessages(null);
Thread.currentThread().isInterrupted();
}
});
}`