views:

490

answers:

1

I have made a java program with GUI and I want a stop button functionality in which when a user clicks on the stop button, the program must be stopped.

  1. In my program, the main thread starts other 10 threads and I want that whenever the stop button has been clicked all the 10 threads must be stopped before the main thread.

  2. Second, I also want that whenever any thread of those 10 threads is stopped, it must first close all the resources it had opened before like connection to a database etc.

I have implemented the code as answered by ........

Now there is one problem.

My thread class is like this:

public class ParserThread implements Runnable {
    private volatile boolean stopped = false;

    public void stopTheThread() {
        stopped = true;
    }
    :
    :
}

And below is the main thread that starts 10 threads from the function start()

public class Main() {
    Thread [] threads;

    public void start() {
        for(int i = 0; i < 10; i++) {
            threads[i] = new Thread(new ParserThread());
        }       
    }

    public void stop() {
        // code to stop all the threads
    }
}

Now I want to call the stop method of the ParserThread to set "stopped = true" to stop the thread. I want this thing to be done for all the 10 threads.

How can I call that stop method. I want it to be done in the stopAllThreads() method of the Main class.

+6  A: 

Generally speaking, the way to do this is to have each of the other threads periodically check a flag. Often background threads loop, waiting for work - they just have to check the flag each time they go round a loop. If they're using Object.wait() or something similar to be told that there's more work, the same notification should be used to indicate that the thread should stop too. (Don't just spin until you're stopped - that will suck CPU. Don't just use sleep - that will delay termination.)

That allows all threads to terminate cleanly, releasing resources appropriately. Other options such as interrupt() and the deprecated destroy() method are much harder to control properly, IMO. (Interrupting a thread is better than hard-aborting it, but it has its own set of problems - such as the interruption is only processed at certain points anyway.)

EDIT: In code, it would look something like:

// Client code
for (Task task : tasks) {
  task.stop();
}

// Threading code
public abstract class Task implements Runnable {

  private volatile boolean stopped = false;

  public void stop() {
    stopped = true;
  }

  protected boolean shouldStop() {
    return stopped;
  }

  public abstract void run();
}

Your tasks would then subclass Task. You would need to make it slightly more complicated if you wanted the stop() method to also notify a monitor, but that's the basic idea.

Sample task:

public class SomeTask extends Task {
  public void run() {
    while (!shouldStop()) {
      // Do work
    }
  }
}
Jon Skeet
can you please explain it pro grammatically. How can I implement it in my program. You can take a look at a portion of my program at http://stackoverflow.com/questions/1611822/how-to-join-one-thread-with-other-in-java
Yatendra Goel
"Periodically checking a flag" is also called "Active Waiting" and not recommenend. Use wait/notify to avoid this.
pimpf0r
@pimpf0r: You only need to use wait/notify if you'd otherwise spin or sleep. If you have a constant stream of work, it's fine. Note that I've mentioned using wait() in the answer if you'd otherwise want to sleep.
Jon Skeet
I think interruption is preferable here. The only real drawback is that isInterrupted() returns false after you've gotten an InterruptException but as long as you know that you can pretty much think of it as the same pattern built in.
Fredrik
@Fredrik: I really don't like interruption... I believe it makes it much harder to write the worker threads in a way which will maintain consistent state. If you tightly control the point in your code at which you exit, you can make sure you're consistent really easily.
Jon Skeet
I sort of agree with you but since the interruption in java is "soft" instead of the old cancellation/stopping method of interruption that was used in the 90's (and in pthreads) I think it is a good compromise. Checking for isInterrupted() returning true isn't harder than checking a variable and even if you do that you still have to catch InterruptExceptions and deal with them. The most important thing though is probably that there is no other good way if you need to sit and wait for something, unless you timeout on a regular basis to check your variable.
Fredrik
I have implemented the above code but there is one problem. I have updated my question to tell you the problem.
Yatendra Goel