Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I safely stop multiple threads?

Tags:

java

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();
      }
    }
}
like image 599
xDG Avatar asked Aug 04 '26 05:08

xDG


2 Answers

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.

like image 55
Dmitri Avatar answered Aug 05 '26 17:08

Dmitri


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.

like image 39
user949300 Avatar answered Aug 05 '26 18:08

user949300



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!