Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Utility of Future.cancel(boolean) method

I was simply exploring the java.util.concurrent package.

I learnt that the class 'Future' has a method boolean cancel(boolean mayInterruptIfRunning)

Please find attached the test code I wrote :

package com.java.util.concurrent;  import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor;  public class FutureTester {  /**  * @param args  * @throws InterruptedException  */ public static void main(String[] args) throws InterruptedException {     // TODO Auto-generated method stub     int poolCnt = 1;     Callable<NumberPrinter> numberPrinter = null;     ScheduledThreadPoolExecutor schPool = new ScheduledThreadPoolExecutor(             poolCnt);     ScheduledFuture<NumberPrinter>[] numPrinterFutures = new ScheduledFuture[poolCnt];     FutureTask<NumberPrinter>[] futureTask = new FutureTask[poolCnt];      for (int i = 0; i < poolCnt; i++) {         numberPrinter = new NumberPrinter();         futureTask[i] = new FutureTask<NumberPrinter>(numberPrinter);          /*          * numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool          * .schedule(futureTask[i], 0, TimeUnit.MILLISECONDS);          */         numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool                 .submit(futureTask[i]);     }      //Thread.sleep(30);      if (numPrinterFutures.length > 0) {          System.out.println("Task completed ? "                 + numPrinterFutures[0].isDone());          System.out.println("Task cancelled ? "                 + numPrinterFutures[0].cancel(true));          System.out.println("Is task cancelled ? "                 + numPrinterFutures[0].isCancelled());     } }  }  class NumberPrinter implements Callable<NumberPrinter> {  private int counter = 10;  @Override public NumberPrinter call() throws Exception {     // TODO Auto-generated method stub      while (counter > 0) {         if (Thread.interrupted()) {/*OUCH !!!*/             return null;         }         System.out.println("counter = " + (counter--));     }      return this; }  } 

Intially,I assumed that cancelling a task will also stop the execution of a running thread(the 'OUCH' part NOT included).But I got the output as follows :

counter = 10 Task completed ? false counter = 9 Task cancelled ? true counter = 8 Is task cancelled ? true counter = 7 counter = 6 counter = 5 counter = 4 counter = 3 counter = 2 counter = 1 

On further reading on stackoverflow itself,it was said that

  1. The 'cancel' method can only stop the 'unstarted' jobs(which contradicts with the api description of the method)
  2. The cancel method simply interrupts the running thread which then must return from the run() method

Hence,I included the 'OUCH' part - a while loop checking for interruption;the output was as follows :

Task completed ? false counter = 10 Task cancelled ? true Is task cancelled ? true 

QUESTION :

If one is supposed to write something analogous to the 'OUCH' part to stop the running thread,what is the utility/value of the cancel method. How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel? What is the design/conceptual/logical part that I am overlooking?

like image 887
Kaliyug Antagonist Avatar asked Mar 02 '12 16:03

Kaliyug Antagonist


People also ask

How does Future cancel work?

cancel() will cancel any queued task or will call Thread. interrupt() on your thread if already running. It's your code's responsibility is to be ready for any interruptions.

What is a future How is it used in ExecutorService?

An example of using Future is working with Thread pools. When one submit a task to ExecutorService which is take a long running time, then it returns a Future object immediately. This Future object can be used for task completion and getting result of computation.

What is Future in Java?

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation.

What is cancel in Java?

The cancel method takes a single boolean argument. If the argument is true , cancel sends the background task an interrupt. Whether the argument is true or false , invoking cancel changes the cancellation status of the object to true . This is the value returned by isCancelled .


1 Answers

How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel?

You want to cancel the task, not the thread running it. Using cancel(true) prevents the task from starting (but doesn't remove it from the queue) and interrupts the thread if the task has started. The Task can ignore the interrupt, but there is no clean way of killing a thread without killing the whole process.

like image 93
Peter Lawrey Avatar answered Sep 21 '22 11:09

Peter Lawrey