Pausing/unpausing a thread upon keypress in Java - java

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.

Related

Resume interrupted thread

I want to resume the work of interrupted thread,please let me know some possible solutions for the same.
class RunnableDemo implements Runnable
{
public void run()
{
while(thread.isInterrupted())
{
try{}
catch(Exception e){ //exception caught}
}
}
}
If exception is caught, thread is interrupted, but even though exception is caught, i want thread to continue its work, so please suggest me some way to overcome this issue.
Thanks in advance
Thread interruption is something you choose to obey when writing a thread. So if you don't want your thread to be interrupted, don't check the interrupted status and continue regardless.
The only time you'll need try/catch statements (with respect to thread interruption) is when calling blocking methods that throw InterruptedException. Then you'll need to avoid letting that exception stop your thread's work.
Of course... you should give some thought about whether this is a suitable way to behave. Thread interruption is a helpful thing and choosing not to adhere to it can be annoying to users of your code.
I have written a reusable code for getting this feature where thread can be pause and resume. Please find the code below. Your can extend PausableTask and override task() method:
public abstract class PausableTask implements Runnable{
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<?> publisher;
protected volatile int counter;
private void someJob() {
System.out.println("Job Done :- " + counter);
}
abstract void task();
#Override
public void run() {
while(!Thread.currentThread().interrupted()){
task();
}
}
public void start(){
publisher = executor.submit(this);
}
public void pause() {
publisher.cancel(true);
}
public void resume() {
start();
}
public void stop() {
executor.shutdownNow();
}
}
Hope this helps. For further details check this link or give me shout in comment section.
http://handling-thread.blogspot.co.uk/2012/05/pause-and-resume-thread.html
A thread get's interrupted only if someone called the interrupt() method of that thread and not because some other random exception was thrown while running your thread as you are thinking.
When the thread's interrupted() method is called, InterruptedException will be thrown in the thread if the thread is in the middle of a blocking operation (eg. IO read).
When the InterruptedException is thrown you should know that the interrupted status is cleared, so the next time you call isInterrupted() in your thread will give you false (even though you just cauth the InterruptedException)
Have this in mind while coding your threads. And if you don't understand what I am talking about stop coding multithreading and go read some books about concurrency in java.
One caveat: If your thread handles an InterruptedException while in a call to a third-party library, then you won't necessarily know how the library reacted to it (i.e., did it leave the library objects in a state when it makes sense for your program to continue using them?)
Some developers (including some library developers) mistakenly assume that an interrupt means, "shut down the program," and all they worry about is closing files, etc.; and not so much about whether the library can continue to be used.
Try it and see, but if you're writing code to control a spacecraft or a nuclear reactor or something, then you may want to do a little extra work to really find out what the library does.
As others already stated, usually interruption is the proper way to cancel a task. If you really need to implement a non-cancellable task, at least make sure to restore the interrupted-state of the thread when you're done with your non-interruptible work:
public void run() {
boolean interrupted = false;
try {
while (true) {
try {
callInterruptibleMethod();
} catch (InterruptedException ex) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted) {
// restore interruption state
Thread.currentThread().interrupt();
}
}
}
(From book: Java Concurrency in Practice)

How to stop a thread created by implementing runnable interface?

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();
}
});
}`

How to stop a java thread gracefully?

I wrote a thread, it is taking too much time to execute and it seems it is not completely done. I want to stop the thread gracefully. Any help ?
The good way to do it is to have the run() of the Thread guarded by a boolean variable and set it to true from the outside when you want to stop it, something like:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Once upon a time a stop() method existed but as the documentation states
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.
That's why you should have a guard..
The bad part about using a flag to stop your thread is that if the thread is waiting or sleeping then you have to wait for it to finish waiting/sleeping. If you call the interrupt method on the thread then that will cause the wait or sleep call to be exited with an InterruptedException.
(A second bad part about the flag approach is that most nontrivial code is going to be utilizing libraries like java.util.concurrent, where the classes are specifically designed to use interruption to cancel. Trying to use the hand rolled flag in a task passed into an Executor is going to be awkward.)
Calling interrupt() also sets an interrupted property that you can use as a flag to check whether to quit (in the event that the thread is not waiting or sleeping).
You can write the thread's run method so that the InterruptedException is caught outside whatever looping logic the thread is doing, or you can catch the exception within the loop and close to the call throwing the exception, setting the interrupt flag inside the catch block for the InterruptedException so that the thread doesn't lose track of the fact that it was interrupted. The interrupted thread can still keep control and finish processing on its own terms.
Say I want to write a worker thread that does work in increments, where there's a sleep in the middle for some reason, and I don't want quitting the sleep to make processing quit without doing the remaining work for that increment, I only want it to quit if it is in-between increments:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
You should not kill Thread from other one. It's considered as fairly bad habit. However, there are many ways. You can use return statement from thread's run method.
Or you can check if thread has already been interrupted and then it will cancel it's work. F.e. :
while (!isInterrupted()) {
// doStuff
}
Make a volatile boolean stop somewhere. Then in the code that runs in the thread, regularly do
if (stop) // end gracefully by breaking out of loop or whatever
To stop the thread, set stop to true.
I think you must do it manually this way. After all, only the code running in the thread has any idea what is and isn't graceful.
You need to send a stop-message to the Thread and the Thread itself needs to take action if the message has been received. This is pretty easy, if the long-running action is inside loop:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
For a thread to stop itself, no one seems to have mentioned (mis)using exception:
abstract class SelfStoppingThread extends Thread {
#Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
A subclass just need to override doRun() normally as you would with a Thread, and call stopSelf() whenever it feels like it wants to stop. IMO it feels cleaner than using a flag in a while loop.

Is it a good way to close a thread?

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.

How do you kill a Thread in Java?

How do you kill a java.lang.Thread in Java?
See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.
The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.
Generally you don't..
You ask it to interrupt whatever it is doing using Thread.interrupt() (javadoc link)
A good explanation of why is in the javadoc here (java technote link)
In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully.
Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.
I would not use a boolean to check whether the thread should terminate. If you use volatile as a field modifier, this will work reliable, but if your code becomes more complex, for instead uses other blocking methods inside the while loop, it might happen, that your code will not terminate at all or at least takes longer as you might want.
Certain blocking library methods support interruption.
Every thread has already a boolean flag interrupted status and you should make use of it. It can be implemented like this:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Source code adapted from Java Concurrency in Practice. Since the cancel() method is public you can let another thread invoke this method as you wanted.
One way is by setting a class variable and using it as a sentinel.
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
Set an external class variable, i.e. flag = true in the above example. Set it to false to 'kill' the thread.
I want to add several observations, based on the comments that have accumulated.
Thread.stop() will stop a thread if the security manager allows it.
Thread.stop() is dangerous. Having said that, if you are working in a JEE environment and you have no control over the code being called, it may be necessary; see Why is Thread.stop deprecated?
You should never stop stop a container worker thread. If you want to run code that tends to hang, (carefully) start a new daemon thread and monitor it, killing if necessary.
stop() creates a new ThreadDeathError error on the calling thread and then throws that error on the target thread. Therefore, the stack trace is generally worthless.
In JRE 6, stop() checks with the security manager and then calls stop1() that calls stop0(). stop0() is native code.
As of Java 13 Thread.stop() has not been removed (yet), but Thread.stop(Throwable) was removed in Java 11. (mailing list, JDK-8204243)
There is a way how you can do it. But if you had to use it, either you are a bad programmer or you are using a code written by bad programmers. So, you should think about stopping being a bad programmer or stopping using this bad code.
This solution is only for situations when THERE IS NO OTHER WAY.
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
I'd vote for Thread.stop().
As for instance you have a long lasting operation (like a network request).
Supposedly you are waiting for a response, but it can take time and the user navigated to other UI.
This waiting thread is now a) useless b) potential problem because when he will get result, it's completely useless and he will trigger callbacks that can lead to number of errors.
All of that and he can do response processing that could be CPU intense. And you, as a developer, cannot even stop it, because you can't throw if (Thread.currentThread().isInterrupted()) lines in all code.
So the inability to forcefully stop a thread it weird.
The question is rather vague. If you meant “how do I write a program so that a thread stops running when I want it to”, then various other responses should be helpful. But if you meant “I have an emergency with a server I cannot restart right now and I just need a particular thread to die, come what may”, then you need an intervention tool to match monitoring tools like jstack.
For this purpose I created jkillthread. See its instructions for usage.
There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.
But, this is just "decent", and not absolute, because the code could catch the ThreadDeath error (or whatever exception you explicitly throw), and not rethrow it like a gentlemanly thread is supposed to do. So, the bottom line is AFAIA there is no absolute fail safe.
'Killing a thread' is not the right phrase to use. Here is one way we can implement graceful completion/exit of the thread on will:
Runnable which I used:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
#Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
The triggering class:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
There is no way to gracefully kill a thread.
You can try to interrupt the thread, one commons strategy is to use a poison pill to message the thread to stop itself
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
#Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
http://anandsekar.github.io/cancel-support-for-threads/
Generally you don't kill, stop, or interrupt a thread (or check wheter it is interrupted()), but let it terminate naturally.
It is simple. You can use any loop together with (volatile) boolean variable inside run() method to control thread's activity. You can also return from active thread to the main thread to stop it.
This way you gracefully kill a thread :) .
Attempts of abrupt thread termination are well-known bad programming practice and evidence of poor application design. All threads in the multithreaded application explicitly and implicitly share the same process state and forced to cooperate with each other to keep it consistent, otherwise your application will be prone to the bugs which will be really hard to diagnose. So, it is a responsibility of developer to provide an assurance of such consistency via careful and clear application design.
There are two main right solutions for the controlled threads terminations:
Use of the shared volatile flag
Use of the pair of Thread.interrupt() and Thread.interrupted() methods.
Good and detailed explanation of the issues related to the abrupt threads termination as well as examples of wrong and right solutions for the controlled threads termination can be found here:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
Here are a couple of good reads on the subject:
What Do You Do With InterruptedException?
Shutting down threads cleanly
I didn't get the interrupt to work in Android, so I used this method, works perfectly:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
Thread.stop is deprecated so how do we stop a thread in java ?
Always use interrupt method and future to request cancellation
When the task responds to interrupt signal, for example, blocking queue take method.
Callable < String > callable = new Callable < String > () {
#Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
When the task does not respond to interrupt signal.Suppose the task performs socket I/O which does not respond to interrupt signal and thus using above approach will not abort the task, future would time out but the cancel in finally block will have no effect, thread will keep on listening to socket. We can close the socket or call close method on connection if implemented by pool.
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}
After 15+ years of developing in Java there is one thing I want to say to the world.
Deprecating Thread.stop() and all the holy battle against its use is just another bad habit or design flaw unfortunately became a reality... (eg. want to talk about the Serializable interface?)
The battle is focusing on the fact that killing a thread can leave an object into an inconsistent state. And so? Welcome to multithread programming. You are a programmer, and you need to know what you are doing, and yes.. killing a thread can leave an object in inconsistent state. If you are worried about it use a flag and let the thread quit gracefully; but there are TONS of times where there is no reason to be worried.
But no.. if you type thread.stop() you're likely to be killed by all the people who looks/comments/uses your code. So you have to use a flag, call interrupt(), place if(!flag) all around your code because you're not looping at all, and finally pray that the 3rd-party library you're using to do your external call is written correctly and doesn't handle the InterruptException improperly.

Categories