1

I have running thread that I would like to stop and later on resume at some point. I learned not to use stop() etc. as these are deprecated and got to this code below that seems to stop thread successfully. It simply exits run method. Now, how can I restart it? If I call start() method it says that thread is still running, so would directly calling run() do in this situation? Would it cause any problems? BTW this is for Android app if that makes any difference.

private volatile stopThread;

public void stopButton() {
    // this is called when button is clicked
    // and thread is already started and running
    stopThread= true;
}

public void run() {

    while (!stopThread) {
        // do something here
    }

    stopThread=false;
}

EDIT: its a timer that starts when thread is started, then can be paused and started again. So timer is a class containing Thread object (I already extend the class with SurfaceView).

spirytus
  • 10,726
  • 14
  • 61
  • 75
  • 1
    Can you elaborate on the conditions where you'd like to resume the thread? – Michael Easter Aug 08 '12 at 01:07
  • You can't call `start` twice on the same thread. Does the thread hold a state that you need to reuse or can you start a brand new thread? – assylias Aug 08 '12 at 01:08
  • 1
    You need `wait()` and `notify()` methods. See [this](http://stackoverflow.com/questions/1036754/difference-between-wait-and-sleep) for some important details. – ffriend Aug 08 '12 at 01:10
  • 6
    By the way, it helps a lot to change the way you are thinking about the problem. You don't want to stop and resume a thread. You want to stop some particular work from getting done and later resume doing that work. This shift in thinking about the problem will lead you to a much more sensible implementation. Focus on the work the thread is doing, why you don't want to do that work, and how you can sensibly reflect that change in desire. (Why is the thread coded to do work you don't want done in the first place?) – David Schwartz Aug 08 '12 at 01:18
  • See also http://stackoverflow.com/questions/3194545/how-to-stop-a-java-thread-gracefully – Raedwald Oct 31 '14 at 18:20

3 Answers3

6

The only safe way to stop and resume a thread safely is to add code at the relevant points in the thread's body to deal with it. (Don't use the deprecated Thread stop / pause / resume because they are fundamentally unsafe.)

Stop without resumption is relatively simple, using either an application-specific flag, or the Thread.interrupt() mechanism. The latter is probably better because some of Java's synchronization and IO APIs are interrupt-aware. However, you do run against the problem that a lot of existing libraries are not interrupt aware, or don't deal with InterruptedException properly.

Stop with resumption is more tricky. You'll need to create your own class something like this:

public class PauseControl {
    private boolean needToPause;

    public synchronized void pausePoint() {
        while (needToPause) {
            wait();
        }
    }

    public synchronized void pause() {
        needToPause = true;
    }

    public synchronized void unpause() {
        needToPause = false;
        this.notifyAll();
    }
}

and add calls to myPauseControl.pausePoint() at relevant points throughout your the thread's code. Note that this won't allow you to pause IO, or activity in "child" threads, and it will only pause at points in your code where you call the pausePoint method. Also you need to beware of creating problems by pausing the thread while it holds locks on something else, or while something else is waiting for it to respond.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
2

The Java 1.4 docs explained why and gave alternatives to the various deprecated Thread methods, including suspend() and resume() by using wait() and notify() instead.

Look for the heading What should I use instead of Thread.suspend and Thread.resume? about halfway down the page. 

Matthias Ronge
  • 9,403
  • 7
  • 47
  • 63
Stephen P
  • 14,422
  • 2
  • 43
  • 67
0

The stop() method of Thread class is deprecated and unsafe for use, because stopping a Thread causes it to unlock all monitors that it had locked. This has damaging consequences, because any of the Objects (previously protected by monitors) in an inconsistent state may now be viewed by other threads in an inconsistent state. This behavior may be subtle and difficult to detect.

You never invoke the run() method directly and if you stop the Thread using your volatile variable approach, the Thread would have TERMINATED. In order to start the Thread perform new Thread().start() again.

Puneith Kaul
  • 364
  • 2
  • 4