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

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

Related

Defining a thread id to a object and interrupt

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.

Java thread doesn't stop/interrupt

I'm trying to terminate a thread but it doesn't interrupt or stop. All of this are part of controller of a software called Webots. I use this to simulate a multi robot system. In the controller of each robot, I start a thread which receive messages through robots receivers. This thread must start at first, and terminate when simulation ends.
The run method for this thread look like this:
public void run() {
while (true)
{
String M = recieveMessage();
char[] chars = M.toCharArray();
if(chars[0]==robotName||chars[0]=='0')
messages.add(M);
}
}
In the main controller I have code that look like this:
MessageThread MT = new MessageThread(messages, receiver,getName());
MT.start();
for (int i = 0; i < 100; i++)
{
try
{
Thread.sleep(25); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(messages.get(messages.size()-1));
}
MT.interrupt();//MT = null;
System.out.println(MT.interrupted());
It's not important what I do in my main controller, so don't judge it. For example, messages is an ArrayList. It's like a buffer which MT put messages in and the main thread reads from. I use it because the receiver and emitter are not synchronized.
If I call interrupt() or MT = null but interrupted() it returns false and MT continues to run. Is there anything wrong in my code?
I read some topics like:
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
How do you kill a Thread in Java?
interrupt() doesn't work
Java: How interrupt/stop a thread?
and so on but I couldn't find any useful answer.
Edit
Thanks everyone, I've made changes to my code. I added this to the MessageThread class:
private volatile boolean isRunning = true;
Then I used while(isRunning) instead of while(true) and I added
public void kill()
{
isRunning = false;
}
and called MT.kill() instead of MT.interrupt().
It worked but I couldn't find out what's wrong with interrupt(). I read the link which #ExtremeCoders recommended. However, I'm still confused. It says "a thread must support its own interruption". So do I have to overwrite the interrupt() method? I can't call interrupt to terminate a thread?
Thanks again.
Interrupting a thread just sets a flag on the thread. If the thread never checks the flag, it won't respond. By creating your own boolean member, you've duplicated that functionality unnecessarily.
Here's the general pattern for what you are trying to do:
#Override
public void run() {
while(!Thread.interrupted() {
/* Do something. */
}
Thread.currentThread().interrupt();
}
This will allow you to call MT.interrupt() as you expected. It's better than creating your own flag and custom method to set it: you can use your Runnable task with high-level tools like ExecutorService and cancellation will work because you used the standard API; same is true for interruption of an entire ThreadGroup.
Calling Thread.interrupted() clears the interruption status of a thread; we set it by calling Thread.currentThread().interrupt(), the status is set again so that callers of run() can detect the interrupted state. This might not always be desirable however.

Java: Calling method from threads one after another

I have class Server and subclass ClientThread. ClientThread has methods receive() and broadcast(String[] msg) used to receive and send messages from/to clients connected to server.
Scheme:
public class Server extends Thread {
private ArrayList<ClientThread> clientThreads;
class ClientThread extends Thread {
public void broadcast(String[] msg) {...}
public void receive() {
...
if (msg.equals("CHANGED")) {
resumeOthers();
}
public void suspendOthers() {
for (ClientThread c: clientThreads)
if (c!=this)
try {
c.wait();
} catch (InterruptedException e) {}
}
public void resumeOthers() {
for (ClientThread c: clientThreads)
if (c!=this)
c.notify();
}
}
public void run() {
...
cmd = new String[1];
cmd[0] = "PROMPTCHANGE";
for (ClientThread currPlayer: clientThreads) {
currPlayer.broadcast(cmd);
currPlayer.suspendOthers();
}
}
}
Now, I would like to make this ClientThreads work one after another, like this:
1. ClientThread number 1 is calling method broadcast.
Now any other ClientThread existing is freezed
(they are stored in ArrayList on Server)
2. Client (another class) replies with a message that is being caught by receive()
Now this thread is freezed, and the next one starts running
Unfortunately, my approach doesn't work.
Could somebody explain me in details how to achieve that?
by calling Object.wait(), you are are suspending the CALLING thread, not the thread that this object happens to be.
so in effect, you are doing a loop that blocks the calling thread N times, definitely not what you intended.
in order to pause a thread, you need to have IT wait on an objet, or have it block entering a synchronized block (or use Thread.sleep(), but usually its not a good solution).
in other words, the client threads need to call wait, not the calling thread.
One addition:
it seems you are new to Java threading and synchronization, I strongly suggest that you read about it before attempting this.
Google around for some docs on the subject.
here is something to get you started:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
It's not clear how the sequence of execution works.
Anyway, as already said by previous answers, calling x.wait() on a Object makes the current thread block on object x. Moreover, in order to call wait() and notify(), you first have to synchronize on that object, AND, when you call wait(), you should do it in a loop, checking for an external condition, because spurious wakeups can happen.
So, the correct pattern should be something like:
void waitForCondition() {
synchronized (lockObject) {
while (!condition) {
lockObject.wait();
}
}
}
void setCondition() {
synchronized (lockObject) {
condition = true;
lockObject.notify(); //or .notifyAll()
}
}
If you want to make the threads run one after another, try http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html

Check execute code when thread is finished

I didn't fully understand the concept of threads I have some questions. Assume we have the following code:
ExecCommand.java
// I don't know how this work, for now
package therads;
// Here we will have the methods and run them from the Main.java
public class ExecCommand implements Runnable
{
String name;
int time;
public ExecCommand(String s,int amount)
{
name = s;
time = amount;
}
// Run method (Runnable)
public void run()
{
try
{
// What to execute when the thread is started
System.out.printf("%s is sleeping for %d\n",name,time);
Thread.sleep(time);
System.out.printf("%s is done\n",name);
}
catch(Exception e)
{
}
}
// This dosen't work when the thread is stopped
public void stop()
{
try
{
System.out.printf("STOPPED!");
}
catch(Exception e)
{
}
}
// This dosen't work when the thread is started
public void start()
{
try
{
System.out.printf("Started!");
}
catch(Exception e)
{
}
}
}
and i call him from :
Main.java
Thread t5 = new Thread(new ExecCommand("Good Function",1000));
t5.start();
I want to println() "Started" when the thread is started and "Stopped" when it finished. It is possible?
When a thread is completed, it dies, complete released from memory? If not, how i can do that?
How can i make a thread that repeat itself like once every 1000 miliseconds till i press a key? I was thinking about while(true) { t5.start; }
but i don't know for sure.
First of all, there is no point in using the start and stop methods. Everything happens in the run method.
To print a message on start and stop, put them at the start and end of the run method. To loop indefinitely and keep executing code until an outside event happens, use a flag and loop on it:
class ThreadTask implements Runnable {
private volatile boolean flag = false;
public void setFlag(boolean value) {
flag = value;
}
public void run() {
System.out.println("Started");
while(!flag) {
// execute code
}
System.out.println("Stopped");
}
}
Then when you want the thread to stop, just set the flag to true using setFlag.
And yes, threads are automatically cleaned up by the runtime + OS after the run method terminates.
Why or when would you expect your .start() and .stop() to be called? Runnable has only a single method in the interface; .run(). The JavaDocs for Thread cover it pretty well. http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html. If you want something to happen when your Thread starts, put that something at the top of your .run(). If you want something to happen when your Thread is finishing, put it at the bottom of the .run(). By-in-large doing anything with the .start() and .stop() methods on Thread is discouraged. Concentrate on doing all you lifecycle stuff within your .run(). And get a copy of "Java Concurrency in Practice" by Goetz. It will show you the full range of your options (including don't do you own Threading directly).
You are not supposed to override the start and stop methods. They are not callback methods.
What you want is something akin to the SwingWorker class (assuming you are interested in UI related threading synchronization).
If not, you can subclass Thread yourself and provide a callback mechanism.
Yes of course. You can just print "Started" in the first line of your run() method, and print "Stopped" either in a finally section of run() method or just after t5.join()
You are not told about the details, and cannot do anything. But you can assume the resources are freed as soon as necessary. (Of course if you have reachable links for any references allocated within your thread, JVM cannot decide that these are of no use, so "complete" is not a proper word here.)
Take a look at java.util.Timer
If you prefer to use System.out.println instead of printf just change those lines of code. There's nothing thread-related about those calls.
The thread will be collected and released from memory by the garbage collector when it has stopped running and there are no live references to it. Same as all objects.
Don't override stop(). This has been deprecated and should really be dealt with by the JVM, not your application code. Just override run to implement whatever you want your thread to do, as per the docs
You can use Thread.sleep to sleep for a period of time. How accurate the sleep will be will depend on your platform and the resolution of the available system clock.

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