简体   繁体   中英

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.

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()

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.

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

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM