Reputation: 575
I am faced with a situation where I need to stop a thread of Executor service from running.
I have already read the solution in other posts which says to make use of Future object and cancel the task.
But I rather tried a different approach.
Please can anyone let me know if there is any issue with this approach.
Following is my Runnable class.
public class TestRunnable implements Runnable {
Thread t;
@Override
public void run() {
// TODO Auto-generated method stub
setT(Thread.currentThread());
while(true)
{
if(Thread.currentThread().isInterrupted())
{
System.out.println("From Inside thread, Exiting");
System.exit(0);
}
}
}
public void setT(Thread t) {
this.t = t;
}
public Thread getT() {
return t;
}
}
Following is my main method:
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ruunTest {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
ExecutorService service = Executors.newCachedThreadPool();
TestRunnable test = new TestRunnable();
service.execute(test);
Thread.sleep(1000);
System.out.println("About to Interrupt");
test.getT().interrupt();
}
}
Upvotes: 4
Views: 10210
Reputation: 1902
Not a good idea to stop a thread voluntarily. Your code is not stopping a thread it actually blocking the whole JVM form progressing further. You actually are missing the whole point of the executor service.
The ideology of the executor is that 'I' have an expanding / contracting list of threads that will do the work for you. 'You' just give me individual, mutually exclusive work jobs to action (Runnables or Callables). The main point to understand here is "you don't worry about threads and their life cycle" ... you just create work items and give them to me to execute. If you don't want to execute a work or want to stop in middle call the cancel
method, else don't worry about it, because once its done 'I' will finish and clean up and provide you the return values if any.
'I' will also manage the thread pool for you but expanding it with more threads when work jobs come in faster and contracting it to lesser threads by "closing idle threads" when jobs are less frequently pouring in.
Now tell me, is it right what you are trying to achieve.
Upvotes: 2
Reputation: 45005
The only proper way to do this is to cancel
the Future
corresponding to your task and in your task, you should check regularly if the thread has been interrupted or not.
Something like that:
public class Task implements Callable<Void> {
@Override
public Void call() throws InterruptedException {
while(true) {
// Check regularly in your code if the thread has been
// interrupted and if so throws an exception to stop
// the task immediately
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Thread interrupted");
}
}
}
}
Then your main code would be:
ExecutorService service = Executors.newCachedThreadPool();
// My task
Task task = new Task();
// Submit the task and get the corresponding future
Future<?> future = service.submit(task);
...
// Cancel the task which will interrupt the thread that was executing the
// task if any
future.cancel(true);
Upvotes: 5
Reputation: 1014
You can use thread.stop
, although it will throw threadDeathError which needs to be handled.
If you use future.cancel
, it will cancel the task but wont kill the thread as thread will go back to thread pool. Thread.stop
will kill the thread.
Upvotes: -2
Reputation: 494
You can use Quasar library for threads, works faster that Java native threads and are easier to use. http://www.paralleluniverse.co/quasar/
Upvotes: -1