Stripies
Stripies

Reputation: 1267

Stopping and Restarting a Thread

I am trying to stop a current thread, change the run() method, and then restart that thread. I've looked around, and most of the methods are deprecated. However, interrupt() is not. I'm not sure if that's all you need to do.

interrupt();
start();

Would that work for what I needed it to do? It says that you should never start a thread more than once, and I don't know if it means

start();
start();

Rather than what I wanted to do.

Any help is appreciated.

Thanks

Upvotes: 0

Views: 9283

Answers (7)

Adam Zalcman
Adam Zalcman

Reputation: 27233

Calling interrupt() will set the thread's interrupt status potentially interrupting blocking methods. This is part of a cooperative cancellation mechanism. You can't use it to force the thread to stop running.

Stopping threads has been deprecated for a reason: it is inherently dangerous as it may leave the state variables which it is manipulating in an inconsistent state.

You should not do this. Make your code from the run() method into a Runnable and submit it for execution to an Executor. This will return you a Future which you can use to retrieve its results as well as to cancel it.

If you want to reuse the same thread for other computations, use a thread pool, see for example Executors.newFixedThreadPool() and other factory methods in Executors.

Upvotes: 1

jbx
jbx

Reputation: 22128

I think you're approaching your problem in the wrong way. You cannot 'change the run() method of a Thread'. However what you probably want is to stop the previous thread and create a new one with a different run() method.

One thing to keep in mind however, is that Threads are designed to be as autonomous as possible and they don't like interference from other threads, which is why suspend() and resume() are deprecated. They create all sorts of bad behaviour depending on the circumstances and also prone to deadlocks.

You have 2 perfectly safe alternatives however:

  1. Use wait() and notify() on a specific shared object.
  2. Use sleep() and interrupt()

You need to decide within the run() method where it is safe to 'stop' the thread, and at that point put a wait() or sleep(). Your thread will only stop at that point.

The other thread can then do a notify() or sleep() so that the running thread is notified or interrupted. In case of interrupt() you will get an InterruptedException which you can use to terminate what you were doing in that thread.

After interrupting the old thread you can start a new thread initialised with a new Runnable implementation which has the different run() method.

Upvotes: 1

Francis Upton IV
Francis Upton IV

Reputation: 19443

You should look into the basics of threading more. A thread can only run once. If you want to have the thread run different code, you need to create a new thread.

The interrupt() method will not stop a thread immediately (there is no supported) way to do that, it will stop only at certain points by throwing an InterruptedException().

Upvotes: 1

korifey
korifey

Reputation: 3509

Don't restart a thread. You ALWAYS can rewrite your buisness logic to do this some other way. Consider using SingleThreadExecutor

Upvotes: 3

Kylar
Kylar

Reputation: 9334

In this case, you should create a Runnable object and pass it to a thread. Then you're creating different threads, but re-using the 'work' object.

Upvotes: 2

paxdiablo
paxdiablo

Reputation: 881223

No, you can't do that. Fron the java online docs:

It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

Upvotes: 4

Brian Agnew
Brian Agnew

Reputation: 272237

Once you've started a thread, you can only interrupt it. Once you've done that, you can't start it again. See here for more details.

I'm not quite sure what you want to do, but it sounds like you have different Runnables that you want to run in sequence. In this case use a SingleThreadExecutor and submit your Runnables. It will run these in order, and so interrupting the first (successfully) will invoke the second.

I'm still not sure this is a good idea (it just doesn't sound right) and perhaps posting a more detailed problem description will give people a better idea of what you're really trying to do.

Upvotes: 1

Related Questions