Tim
Tim

Reputation: 4365

Java Threads - Stopping a thread from running via another thread making a method call

I have a Runnable class that I'm writing. Inside of it, I have two methods. The run() method, and another method called stopRunning(). stopRunning() is to be called by a separate thread from the one that's running the run() method and is to stop the thread running the run() method from running.

Here's a code snippet:

public class myRunnable implements Runnable
{
    private boolean stillRunning = true;

    public void stopRunning()
    {
        synchronized (this)
        {
           stillRunning = false;
        }
    }

    public void run()
    {
       while (stillRunning)
       {
          synchronized (this)
          {
             // do some stuff that doesn't involve the isPlaying var
          }
       }
    }

}

Does this code look correct? Do I need to synchronize to ensure that the change of isPlaying will be recognized by the thread running the run() method?

Also, do I need to call notify() or notifyAll() anywhere here for this to work? I'm pretty sure I don't since I never call wait(), but I'm not 100% sure.

EDIT: woops, my code was wrong. I used the wrong name for the boolean, sorry about that. It's fixed now.

Upvotes: 1

Views: 1234

Answers (4)

GETah
GETah

Reputation: 21449

For the starting and stopping a thread, the Java Thread API already provides the functionality you are looking for. Thread.interrupt() and Thread.interrupted() can be used to achieve what you want.

public class MyThread extends Thread{
  public void run(){
    while(!interrupted()){
      try{
        // Place your code here
      }catch(InterruptedException e){
        break;
      }
    }
  }
}

Whenever you want to interrupt MyThread just call MyThread.interrupt()

Upvotes: 3

seand
seand

Reputation: 5296

For reliability, you need to apply some MT protection to the 'stillRunning' variable. You can make this volatile as other noted. Or, you can wrap it in a synchronized block. That may be useful if other things need to occur besides setting/checking 'stillRunning'.

Note that without MT protection, your code may appear to work in things like unit tests that don't run under heavy load. But it won't be reliable in a production setting.

Regarding your comment about notify(), notifyAll(); this is used to wake up threads that are blocked and to signal that it proceed to check state. Your example doesn't appear to do need this. Nowadays notify() / wait() is considered pretty low level and Java has some threading APIs to deal with this (ex. latches).

Upvotes: 0

Nav
Nav

Reputation: 10442

you should declare stillRunning as a volatile variable something like this

public class OurThread extends Thread(){
  private volatile boolean stop = false;
  public void run(){
    while (!stop) {
    //Do your actions
    }
  }
}

check this link http://www.asjava.com/core-java/three-ways-to-stop-java-thread/

also check this link about volatile variables http://www.javamex.com/tutorials/synchronization_volatile.shtml

Upvotes: 1

Affe
Affe

Reputation: 47994

That works fine, a more simple alternative that won't cause you synchronization headaches later if you add more features, is to simply declare sillRunning to be volatile.

And as you say, nofity() only does anything useful in combination with wait. It has nothing to do with what you're doing here.

Upvotes: 1

Related Questions