简体   繁体   中英

How do I safely stop multiple threads?

I have created a little example(below) on my attempt to safely stop multiple threads when a user clicks on a Stop button on the user interface. However it seems like after this attempt, the threads still seems to be running. Can you please point me in the right direction?

Edit

Thanks for the comments everyone, just to go along with the post, I have modified the code below with the volatile boolean flag, and it seems to be working fine until I do some I/O operations.
If I add I/O operations, the threads seems to be running even if call fstream.close and then call the stop function to turn the boolean flag on... (Profiled the program to double-check that the threads were still running). Is there any other thing I need to do in order to take care of the opened files, and eventually stop the threads?
Thanks again.

Fixed and working code.

class MultiThreadExample implements Runnable {
    private static final MultiThreadExample threadObj = new MultiThreadExample();
    ArrayList<Thread> threadList = new ArrayList<Thread>();

    public static MultiThreadExample getInstance() {
      return threadObj;
    }

    public void tester() {
      File file = new File("data/");
      File[] files = file.listFiles();
      for (int i = 0; i < files.length; i++) {
        Thread thread = new Thread(new ThreadedCrawler(), files[i].toString());
        thread.start();
        threadList.add(thread);
      }
    }

    public void run() {
      try {
        ProgramTester.getInstance().doSomething();          
      }
      finally { 
        do other stuff 
      }
    }


    public synchronized void stop() throws IOException {
      for (Thread threads : threadList) 
         threads.interrupt();
    }

    public void doSomething() {
      FileInputStream fstream = new FileInputStream(file);
      BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
      String inLine;
      while (((inLine = br.readLine()) != null) &&  !Thread.currentThread().isInterrupted()) {
        do something...
           for()...
               ....
               }
    }
}

public class GuiExample extends JFrame {
    ....
    public void mousePressed(MouseEvent e) {
      try {
        MultiThreadExample.getInstance().stop();
      }
      catch (InterruptedException e1) {
        e1.printStackTrace();
      }
    }
}

interrupt() doesn't stop the thread (see the API). The preferred way of handling this is for your run() method to periodically check a flag and exit when it's set (of course you set the flag when you want terminate the thread).

stop() kills the thread, but it's been deprecated for a long time (with good reason).

same question here

Update

Since you check the flag outside of doSomething() , it won't exit until the method completes, so long running tasks (like file io) will continue.

Move the check to the loop over br.readLine() , as others have suggested, using interrupt() / isInterrupted() is probably better here, since it will also stop threads blocked on io.

interrupt() will stop the thread, iff they periodically check isInterrupted() or interrupted(). Which is now common practice - preferable, IMO, to periodically checking a flag as suggested by @Dmitri.

But, for this to work, you need to make sure that your threads/Runnables periodically check their interrupt status.

Stopping threads in Java is a cooperative process.

First there must be a mechanism to signal the desire for the thread to stop (called by another thread). Thread.interrupt is a built-in method of doing this.

Secondly the target thread must cooperate and obey the 'stop' signal whatever that may be.

One method is for a thread to call interrupt on the target thread. The target thread should periodically call Thread.interrupted and if it returns true terminate gracefully.

Another approach is to use a volatile boolean flag which a thread sets to true to terminate and the target thread checks the flag periodically. To be honest this approach is pretty much a hand-rolled interruption system.

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