Defining a thread id to a object and interrupt - java

I have threads dedicated to users on a system, and I want to be able to stop them individually, do I store the ID of the thread with the userdata at creation and then call an interrupt? or can I somehow add the thread to my user objects and just call it like myuser.mythread.interrupt(); or is this whishing for magic?
Currently I can stop them all and restart without the thread I want.
But that is a time consuming task and also triggers a lag where users must wait.
Update, can this be an answer?
if(delete==true) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete=false;
}
}
Update
I managed to find a way to use myuser.mythread.interrupt();
Or sort of..
I added the thread as a sub class to the user class and created a method in the user class to start and interrupt, now i can start and stop threads with
online.get(1).hellos();
online.get(1).hellosStop();
Instead of having to create a reference and keeping track of anything else than the user objects.
Update (regarding accepted answer, using the id as a reference I could do it this way)
public class MyRunnable implements Runnable {
private boolean runThread = true;
#Override
public void run() {
try {
while (runThread) {
if(delete==true) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete=false;
}
}
Thread.sleep(5);
}
}
catch (InterruptedException e) {
// Interrupted, no need to check flag, just exit
return;
}
}
}

You can just store the Thread reference, perhaps in a WeakReference so that the thread will go away if it exits on its own.
But you can also have the Thread check an AtomicBoolean (or volatile boolean) every now and then to see if it was interrupted, that way you don't need a reference to the thread.
Note though that stopping threads in Java is not possible without cooperation from the thread you want to stop. It doesn't matter if you use interrupt or a boolean that it checks, in both cases it is up to the thread to check these flags (interrupt just sets a flag) and then perform some action like exiting.
Update
A sample interruptable thread class:
public class MyRunnable implements Runnable {
private final AtomicBoolean stopFlag;
public MyRunnable(AtomicBoolean stopFlag) {
this.stopFlag = stopFlag;
}
#Override
public void run() {
try { // Try/Catch only needed if you use locks/sleep etc.
while (!stopFlag.get()) {
// Do some work, but remember to check flag often!
}
}
catch (InterruptedException e) {
// Interrupted, no need to check flag, just exit
return;
}
}
}

The best approach is to save the Thread reference and make it available to the code that needs to interrupt it.
It is technically possible (for a non-sandboxed application) to traverse the tree of all of the JVM's existing threads testing each one. However, that is expensive and doesn't scale. And if you can store or pass the id of a thread, then you should be able to store or pass the Thread reference instead.
It is also technically possible to create your own WeakHashMap<Long, Thread> and use that to map thread ids to threads. But the same argument applies ....
You ask if this is a solution:
if (delete) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete = false;
}
}
No it isn't. Or more precisely, it will only "work" in the case where the thread is interrupting itself. In other cases, the target thread won't be interrupted.
Depending on your use-case, another way to do this could be to use an ExecutionService rather than bare threads. The submit methods return a Future object that represents the submitted task. The object has a cancel(...) method that can be used to cancel the task, either before it runs, or by interrupting the running thread.

Related

Safely pausing and resuming a thread

I want to create a thread to make some HTTP requests every few seconds and is easy to pause and resume at a moments notice.
Is the way below preferred, safe and efficient?
public class Facebook extends Thread {
public boolean running = false;
public void startThread() {
running = true;
}
public void stopThread() {
running = false;
}
public void run() {
while(true) {
while(running) {
//HTTP Calls
Facebook.sleep(2000);
}
}
}
}
Your Code:
In your example, the boolean should be volatile boolean to operate properly. The other issue is if running == false your thread just burns CPU in a tight loop, and you probably would want to use object monitors or a Condition to actually wait idly for the flag to become true again.
Timer Option:
I would suggest simply creating a Timer for this. Each Timer implicitly gets its own thread, which is what you are trying to accomplish.
Then create a TimerTask (FacebookTask below is this) that performs your task and from your main control class, no explicit threads necessary, something like:
Timer t;
void resumeRequests () {
if (t == null) { // otherwise its already running
t = new Timer();
t.scheduleAtFixedRate(new FacebookTask(), 0, 2000);
}
}
void pauseRequests () {
if (t != null) { // otherwise its not running
t.cancel();
t = null;
}
}
Note that above, resumeRequests() will cause a request to happen immediately upon resume (as specified by the 0 delay parameter); you could theoretically increase the request rate if you paused and resumed repeatedly in less than 2000ms. This doesn't seem like it will be an issue to you; but an alternative implementation is to keep the timer running constantly, and have a volatile bool flag in the FacebookTask that you can set to enable/disable it (so if it's e.g. false it doesn't make the request, but continues checking every 2000ms). Pick whichever makes the most sense for you.
Other Options:
You could also use a scheduled executor service as fge mentions in comments. It has more features than a timer and is equally easy to use; they'll also scale well if you need to add more tasks in the future.
In any case there's no real reason to bother with Threads directly here; there are plenty of great tools in the JDK for this job.
The suggestion to using a Timer would work better. If you want to do the threading manually, though, then something more like this would be safer and better:
class Facebook implements Runnable {
private final Object monitor = new Object();
public boolean running = false;
public void startThread() {
synchronized (monitor) {
running = true;
monitor.notifyAll();
}
}
public void stopThread() {
synchronized (monitor) {
running = false;
}
}
#Override
public void run() {
while(true) {
try {
synchronized (monitor) {
// Wait until somebody calls startThread()
while (!running) {
monitor.wait();
}
}
//HTTP Calls
Thread.sleep(2000);
} catch (InterruptedException ie) {
break;
}
}
}
}
Note in particular:
You should generally implement Runnable instead of subclassing Thread, then use that Runnable to specify the work for a generic Thread. The work a thread performs is not the same thing as the thread itself, so this yields a better model. It's also more flexible if you want to be able to perform the same work by other means (e.g. a Timer).
You need to use some form of synchronization whenever you want two threads to exchange data (such as the state of the running instance variable). There are classes, AtomicBoolean for example, that have such synchronization built in, but sometimes there are advantages to synchronizing manually.
In the particular case that you want one thread to stop work until another thread instructs it to continue, you generally want to use Object.wait() and a corresponding Object.notify() or Object.notifyAll(), as demonstrated above. The waiting thread consumes zero CPU until it is signaled. Since you need to use manual synchronization with wait/notify anyway, there would be no additional advantage to be gained by using an AtomicBoolean.
Edited to add:
Since apparently there is some confusion about how to use this (or the original version, I guess), here's an example:
class MyClass {
static void main(String[] args) {
FaceBook fb = new FaceBook();
Thread fbThread = new Thread(fb);
fbThread.start();
/* ... do stuff ... */
// Pause the FaceBook thread:
fb.stopThread();
/* ... do more stuff ... */
// Resume the FaceBook thread:
fb.startThread();
// etc.
// When done:
fbThread.interrupt(); // else the program never exits
}
}
I Would recommend you to use a guarded blocks and attach the thread to a timer

Given two Java threads, stop one thread when one of them finishes

I'm looking for a clean design/solution for this problem: I have two threads, that may run as long as the user wants to, but eventually stop when the user issues the stop command. However if one of the threads ends abruptly (eg. because of a runtime exception) I want to stop the other thread.
Now both threads execute a Runnable (so when I say 'stop a thread' what I mean is that I call a stop() method on the Runnable instance), what I'm thinking is to avoid using threads (Thread class) and use the CompletionService interface and then submit both Runnables to an instance of this service.
With this I would use the CompletionService's method take(), when this method returns I would stop both Runnables since I know that at least one of them already finished. Now, this works, but if possible I would like to know of a simpler/better solution for my case.
Also, what is a good solution when we have n threads and as soon as one of them finishes to stop execution of all the others ?
Thanks in advance.
There is no Runnable.stop() method, so that is an obvious non-starter.
Don't use Thread.stop()! It is fundamentally unsafe in the vast majority of cases.
Here are a couple of approaches that should work, if implemented correctly.
You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)
You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes.
I know Runnable doesn't have that method, but my implementation of Runnable that I pass to the threads does have it, and when calling it the runner will finish the run() method (something like Corsika's code, below this answer).
From what I can tell, Corsika's code assumes that there is a stop() method that will do the right thing when called. The real question is how have you do implemented it? Or how do you intend to implement it?
If you already have an implementation that works, then you've got a solution to the problem.
Otherwise, my answer gives two possible approaches to implementing the "stop now" functionality.
I appreciate your suggestions, but I have a doubt, how does 'regularly check/call' translate into code ?
It entirely depends on the task that the Runnable.run() method performs. It typically entails adding a check / call to certain loops so that the test happens reasonably often ... but not too often. You also want to check only when it would be safe to stop the computation, and that is another thing you must work out for yourself.
The following should help to give you some ideas of how you might apply it to your problem. Hope it helps...
import java.util.*;
public class x {
public static void main(String[] args) {
ThreadManager<Thread> t = new ThreadManager<Thread>();
Thread a = new MyThread(t);
Thread b = new MyThread(t);
Thread c = new MyThread(t);
t.add(a);
t.add(b);
t.add(c);
a.start();
b.start();
c.start();
}
}
class ThreadManager<T> extends ArrayList<T> {
public void stopThreads() {
for (T t : this) {
Thread thread = (Thread) t;
if (thread.isAlive()) {
try { thread.interrupt(); }
catch (Exception e) {/*ignore on purpose*/}
}
}
}
}
class MyThread extends Thread {
static boolean signalled = false;
private ThreadManager m;
public MyThread(ThreadManager tm) {
m = tm;
}
public void run() {
try {
// periodically check ...
if (this.interrupted()) throw new InterruptedException();
// do stuff
} catch (Exception e) {
synchronized(getClass()) {
if (!signalled) {
signalled = true;
m.stopThreads();
}
}
}
}
}
Whether you use a stop flag or an interrupt, you will need to periodically check to see whether a thread has been signalled to stop.
You could give them access to eachother, or a callback to something that had access to both so it could interrupt the other. Consider:
MyRunner aRunner = new MyRunner(this);
MyRunner bRunner = new MyRunner(this);
Thread a = new Thread(aRunner);
Thread b = new Thread(brunner);
// catch appropriate exceptions, error handling... probably should verify
// 'winner' actually is a or b
public void stopOtherThread(MyRunner winner) {
if(winner == aRunner ) bRunner .stop(); // assumes you have stop on class MyRunner
else aRunner.stop();
}
// later
a.start();
b.start();
// in your run method
public void run() {
// la de da de da
// awesome code
while(true) fork();
// other code here
myRunnerMaster.stopOtherThread(this);
}

What is the correct way to pass data to a running thread

In most cases when you create your thread you can prepare the data beforehand and pass it into the constructor or method.
However in cases like an open socket connection you will typically already have a thread created but wish to tell it to perform some action.
Basic idea:
C#
private Thread _MyThread = new Thread(MyMethod);
this._MyThread.Start(param);
Java
private Thread _MyThread = new Thread(new MyRunnableClass(param));
this._MyThread.start();
Now what?
So what is the correct way to pass data to a running thread in C# and Java?
One way to pass data to a running thread is by implementing Message Queues. The thread that wants to tell the listening thread to do something would add an item to the queue of the listening thread. The listening thread reads from this thread in a blocking fashion. Causing it to wait when there are no actions to perform. Whenever another thread puts a message in the queue it will fetch the message, depending on the item and it's content you can then do something with it.
This is some Java / pseudo code:
class Listener
{
private Queue queue;
public SendMessage(Message m)
{
// This will be executed in the calling thread.
// The locking will be done either in this function or in the Add below
// depending on your Queue implementation.
synchronize(this.queue)
{
this.queue.put(m);
}
}
public Loop()
{
// This function should be called from the Listener thread.
while(true)
{
Message m = this.queue.take();
doAction(m);
}
}
public doAction(Message m)
{
if (m is StopMessage)
{
...
}
}
}
And the caller:
class Caller
{
private Listener listener;
LetItStop()
{
listener.SendMessage(new StopMessage());
}
}
Of course, there are a lot of best practices when programming paralllel/concurrent code. For example, instead of while(true) you should at the least add a field like run :: Bool that you can set to false when you receive a StopMessage. Depending on the language in which you want to implement this you will have other primitives and behaviour to deal with.
In Java for example you might want to use the java.util.Concurrent package to keep things simple for you.
Java
You could basically have a LinkedList (a LIFO) and proceed (with something) like this (untested) :
class MyRunnable<T> implements Runnable {
private LinkedList<T> queue;
private boolean stopped;
public MyRunnable(LinkedList<T> queue) {
this.queue = queue;
this.stopped = false;
}
public void stopRunning() {
stopped = true;
synchronized (queue) {
queue.notifyAll();
}
}
public void run() {
T current;
while (!stopped) {
synchronized (queue) {
queue.wait();
}
if (queue.isEmpty()) {
try { Thread.sleep(1); } catch (InterruptedException e) {}
} else {
current = queue.removeFirst();
// do something with the data from the queue
}
Thread.yield();
}
}
}
As you keep a reference to the instance of the LinkedList given in argument, somewhere else, all you have to do is :
synchronized (queue) {
queue.addLast(T); // add your T element here. You could even handle some
// sort of priority queue by adding at a given index
queue.notifyAll();
}
Edit: Misread question,
C#
What I normally do is create a Global Static Class and then set the values there. That way you can access it from both threads. Not sure if this is the preferred method and there could be cases where locking occurs (correct me if I'm wrong) which should be handled.
I haven't tried it but It should work for for the threadpool/backgroundworker as well.
One way I can think of is through property files.
Well, it depends a lot on the work that the thread is supposed to do.
For example, you can have a thread waiting for a Event (e.g. ManualResetEvent) and a shared queue where you put work items (can be data structures to be processed, or more clever commands following a Command pattern). Somebody adds new work to the queue ad signals the event, so the trhread awakes, gets work from the queue and start performing its task.
You can encapsulate this code inside a custom queue, where any thread that calls the Deque methods stops until somebody calls Add(item).
On the other hand, maybe you want to rely on .NET ThreadPool class to issue tasks to execute by the threads on the pool.
Does this example help a bit?
You can use delegate pattern where child threads subscribes to an event and main thread raises an event, passing the parameters.
You could run your worker thread within a loop (if that makes sense for your requirement) and check a flag on each execution of the loop. The flag would be set by the other thread to signal the worker thread that some state had changed, it could also set a field at the same time to pass the new state.
Additionally, you could use monitor.wait and monitor.pulse to signal the state changes between the threads.
Obviously, the above would need synchronization.

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.

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