Re: FutureTask.cancel() - can anyone explain the mechanism?
Daniel Pitts wrote:
Actually, its not the JLS, but the Executor Service that specifies what
to do with that re-thrown error. It does get propagated, but probably
caught and ignored by the worker thread.
Yup, I re-read the JLS, and that's what it says. I don't see any docs
on how to set the error handler for a ExecutorService. I tried setting
an uncaught exception handler and it didn't work. Bummer.
package example;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
public class FutureTaskCancelExample
{
private static class MyCallable implements Callable<Void>
{
private final BlockingQueue<String> blockingQueue =
new LinkedBlockingQueue<String>();
public void put( final String message )
{
try {
blockingQueue.put( message );
}catch( Throwable t ) {
t.printStackTrace();
}
}
public Void call()
{
try {
for( ;; ) {
String message = null;
message = blockingQueue.take();
System.out.println( message );
}
}catch( InterruptedException t ) {
t.printStackTrace();
// preserve for error testing
System.err.println( "Throwable caught in call() " +
t.getCause().getMessage() );
}finally {
System.out.println( "Entered call() finally block." );
}
return null;
}
}
public static void main( String[] args ) throws InterruptedException
{
final ExecutorService executor =
Executors.newSingleThreadExecutor( new ThreadFactory()
{
ThreadFactory defaultFact = Executors.defaultThreadFactory();
public Thread newThread( Runnable r )
{
Thread t = defaultFact.newThread( r );
t.setUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler()
{
public void uncaughtException( Thread t, Throwable e )
{
System.err.println( "Uncaught " + e + " in " + t );
}
} );
return t;
}
} );
final MyCallable myCallable = new MyCallable();
final Future<?> myFuture = executor.submit( myCallable );
myCallable.put( "Go Southend United FC!" );
Thread.sleep( 300 ); // ADDED
myFuture.cancel(true);
executor.shutdown();
}
}