[concurrency-interest] Calling Future.get() after callingFuture.cancel() returned false

Jason Mehrens jason_mehrens at hotmail.com
Fri Mar 2 10:56:14 EST 2007


>If the task has already completed, then cancel returns false.
My understanding is false could also mean already cancelled and get could 
throw the CancellationException then.  True could mean in progress, in which 
case an exception still might occur.  I would assume that these exceptions 
would be of interest too.

>In particular, if the task has finished then a subsequent cancel()
>will be ignored and a subsequent get() will return the result or
>exception generated by the task.
Thanks for clearing that up.  My misunderstanding.


Here is a WOMBAT question: What if cancel throws an exception?  The 
documentation does not list the possible SecurityException or the possible 
RuntimeException/Error from done().  Should a subsequent cancel be allowed 
to interrupt the runner if the first attempt was by a thread with out thread 
modify permission?

Jason


//Test case for Future fun.
import java.util.concurrent.*;
import java.util.*;
public class Cancel implements Callable<Void> {
    private final long sleep_ms;

    public static void main(String[] args) {
        cancelBeforeRun();
        cancelAfterRun();
        cancelCancelRun();
        lateArrivingGet(false);
        lateArrivingGet(true);
        securityCancel(false);
        securityCancel(true);
        evilDone();
        exit();
    }

    private static void cancelAfterRun() {
        System.err.println("cancelAfterRun");
        FutureTask task = new FutureTask(new Cancel(0L));
        task.run();
        testGoldenRule(task, false);
    }

    private static void cancelBeforeRun() {
        System.err.println("cancelBeforeRun");
        FutureTask task = new FutureTask(new Cancel(0L));
        testGoldenRule(task, false);
    }

    private static void cancelCancelRun() {
        System.err.println("cancelCancelRun");
        FutureTask task = new FutureTask(new Cancel(0L));
        task.cancel(false);
        testGoldenRule(task, false);
    }

    private static void lateArrivingGet(boolean mi) {
        System.err.println("lateArrivingGet("+ mi +')');
        FutureTask task = new FutureTask(new Cancel(15 * 1000L)) {
            public void run() {
                super.run();
                exit();
            }
        };
        new Thread(task).start();
        try {
            Thread.sleep(1000L);
        }
        catch(InterruptedException IE) {
            throw new AssertionError(IE);
        }
        testGoldenRule(task, mi);
    }

    private static void evilDone() {
        System.err.println("evilDone");
        FutureTask task = new FutureTask(new Cancel(15 * 1000L)) {
            protected void done() {
                if(super.isCancelled()) {
                    throw new InternalError();
                }
            }
        };
        testGoldenRule(task, false);
    }

    public static void securityCancel(boolean mi) {
            FutureTask task = new FutureTask(new Cancel(15 * 1000L)) {
                public void run() {
                    super.run();
                    exit();
                }
            };

            new Thread(task).start();
            try {
                Thread.sleep(1000L);
            }
            catch(InterruptedException IE) {
                throw new AssertionError(IE);
            }

       try {
            System.setSecurityManager(new SecurityManager() {
             public void checkAccess(Thread t) {
                 throw new SecurityException(t.toString());
             }
            });
            testGoldenRule(task, mi);
        }
        finally {
            System.setSecurityManager(null);
        }
    }


    private static void testGoldenRule(Future task, boolean mi) {
        try {
            if(!task.cancel(mi)) {
                try {
                    try {
                        task.get(0L, TimeUnit.NANOSECONDS);
                        throw new AssertionError("Get returned.");
                    }
                    catch(TimeoutException TE) {
                       if(task.isCancelled() && !task.isDone()) {
                            new AssertionError("Cancelled but not done.")
                            .initCause(TE).printStackTrace();
                       }
                       else {
                           task.get();
                           throw new AssertionError("Get returned.");
                       }
                    }
                }
                catch(InterruptedException IE) {
                    throw new AssertionError(IE);
                }
                catch(ExecutionException EE) {
                    EE.printStackTrace();
                }
                catch(CancellationException CE) {
                    new 
AssertionError(CE.toString()).initCause(CE).printStackTrace();
                }
            }
            else {
                System.err.println("Pass (cancel was true).");
            }
        }
        catch(SecurityException SE) {
            SE.printStackTrace();
            try {
                testGoldenRule(task, mi);
            }
            catch(SecurityException again) {
                System.err.println("Pass (failed twice).");
            }
        }
        catch(InternalError IE) {
            IE.printStackTrace();
            testGoldenRule(task, mi);
        }
    }

    private static void exit() {
        System.err.println(new Date(System.currentTimeMillis()) +", "+
                Thread.currentThread());

    }

    public Cancel(final long sleep_ms) {
        this.sleep_ms = sleep_ms;
    }

    public Void call() throws Exception {
        Thread.sleep(sleep_ms);
        throw new Exception("Pass");
    }
}

_________________________________________________________________
Mortgage rates as low as 4.625% - Refinance $150,000 loan for $579 a month. 
Intro*Terms  
https://www2.nextag.com/goto.jsp?product=100000035&url=%2fst.jsp&tm=y&search=mortgage_text_links_88_h27f6&disc=y&vers=743&s=4056&p=5117



More information about the Concurrency-interest mailing list