Java Thread problem
I want to stop threads using boolean field. I followed the code for this that looks like this:
My thread class looks 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 start () function
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 from ParserThread to set "stop = true" to stop the thread. I want this to be done for all 10 threads.
How can I call this stop method. I want this to be done in the stopAllThreads () method of the main class.
source to share
Here is another alternative approach using ExecutorService . It requires less code than it manipulates threads directly and offers two alternative methods for stopping worker threads. It also allows you to potentially capture the results of each work item (if you have to use Callable instances instead of Runnables). Even if you don't want to capture the explicit return value, it makes it easy to rollback any exceptions to the main thread.
// Array of Runnables that we wish to process.
ParserThread[] parserThreads = ...
// Create executor service containing as many threads as there are Runnables.
// (Could potentially have less threads and let some work items be processed
// sequentially.)
ExecutorService execService = Executors.newFixedThreadPool(parserThreads.length);
// Submit each work item. Could potentially store a reference to the result here
// to capture exceptions.
for (ParserThread runnable : parserThreads) {
execService.submit(runnable);
}
Then, to disable all threads, you can either call:
executorService.shutDown(); // Initiates an orderly shut-down of the service.
... or
executorService.shutDownNow(); // Stops all tasks, interrupting waiting tasks.
source to share
Take a look at Executor . If you are using ExecutorService you can submit all your work as Runnables
. The executor framework will keep track of all these threads, and all managed threads will receive an interupt using the method shutdownNow()
.
Your threads will need to handle the interrupt properly. See this article for details .
It is generally easier to use the Executor framework to manage sets of threads, collect results, handle exceptions, etc.
source to share
You have to keep the ParserThread objects themselves:
public class Main() {
ParserThread[] parserthreads = new ParserThread[10];
public void start() {
for(int i = 0; i < 10; i++) {
parserthreads[i] = new ParserThread();
new Thread(parserthreads[i]).start();
}
}
public void stop() {
for (int i = 0; i < 10; i++) {
parserthreads[i].stopTheThread();
}
}
}
If you need the Thread objects themselves (e.g. to join()
with them), either track them separately, or inherit ParserThread from Thread:
public class ParserThread extends Thread {
private volatile boolean stopped = false;
public void stopTheThread() {
stopped = true;
}
}
Also, as other others have pointed out, it is stopTheThread()
useless to duplicate a method interrupt
in a class Thread
, so your best bet is:
public class Main() {
Thread[] parserthreads = new Thread[10];
public void start() {
for(int i = 0; i < 10; i++) {
parserthreads[i] = new Thread(new ParserThread());
parserthreads[i].start();
}
}
public void stop() {
for (int i = 0; i < 10; i++) {
parserthreads[i].interrupt();
}
}
}
and then in ParserThread call if (Thread.currentThread().isInterrupted())
as often as you can.
source to share
1) There is no need to have any additional volatile variable to signal the termination of the flow; what is interrupted for. In the run () method of the Stream Runnable, you
while (!Thread.currentThread().isInterrupted()) {
// do whatever your thing is
// some things, like sleeping, can throw InterruptedException when
// interrupted, so
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
// clean up here
2) Then, to ask to suspend the process, you simply
threads[i].interrupt();
Voila.
source to share
public class ParserThread implements Runnable {
private static volatile boolean stopped = false;
public static void stopTheThread() {
stopped = true;
}
}
Declare stopped static, and when you set it to false, all versions of ParserThread will see visibility.
Just call
ParserThread.stopTheThread();
Edit so that this will only affect the state of your stopped boolean flag. Obviously this won't stop your threads :)
source to share