AbstractIoFuture implements IoFuture<V> { @Override public boolean cancel(boolean mayInterruptIfRunning) { LOG.debug("Attempting to cancel"); CancellationException ce = null; synchronized (latch) { if (!isCancelled() && !isDone() && cancelOwner(mayInterruptIfRunning)) { LOG.debug("Successfully cancelled"); ce = new CancellationException(); result.set(ce); } else { LOG.debug("Unable to cancel"); } latch.countDown(); } if (ce != null) { LOG.debug("Calling listeners"); for (IoFutureListener<V> listener : listeners) { scheduleException(listener, ce); } } return ce != null; }  @Override @SuppressWarnings({ "unchecked" }) IoFuture<V> register(IoFutureListener<V> listener); @Override boolean cancel(boolean mayInterruptIfRunning); @Override boolean isCancelled(); @Override boolean isDone(); @Override @SuppressWarnings({ "unchecked" }) V get(); @Override @SuppressWarnings({ "unchecked" }) V get(long timeout, TimeUnit unit);  }
@Test public void testCancel() throws Exception { final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>()); doReturn(true).when(future).cancelOwner(anyBoolean()); assertFalse(future.isCancelled()); assertFalse(future.isDone()); assertTrue(future.cancel(false)); assertTrue(future.isCancelled()); assertTrue(future.isDone()); assertFalse(future.cancel(false)); assertTrue(future.isCancelled()); assertTrue(future.isDone()); try { future.get(); fail("This future was canceled"); } catch (final CancellationException ignore) { } }