package ch21concurrent.examples;
import java.util.concurrent.*;
/**
* BackgroundTask
* <p/>
* Background task class supporting cancellation, completion notification, and progress notification
*
* @author Brian Goetz and Tim Peierls
*/
public abstract class BackgroundTask<V> implements Runnable, Future<V> {
private final FutureTask<V> computation = new Computation();
private class Computation extends FutureTask<V> {
public Computation() {
super(new Callable<V>() {
public V call() throws Exception {
return BackgroundTask.this.compute();
}
});
}
protected final void done() {
GuiExecutor.instance().execute(new Runnable() {
public void run() {
V value = null;
Throwable thrown = null;
boolean cancelled = false;
try {
value = get();
} catch (ExecutionException e) {
thrown = e.getCause();
} catch (CancellationException e) {
cancelled = true;
} catch (InterruptedException consumed) {
} finally {
onCompletion(value, thrown, cancelled);
}
}
;
});
}
}
protected void setProgress(final int current, final int max) {
GuiExecutor.instance().execute(new Runnable() {
public void run() {
onProgress(current, max);
}
});
}
// Called in the background thread
protected abstract V compute() throws Exception;
// Called in the event thread
protected void onCompletion(V result, Throwable exception,
boolean cancelled) {
}
protected void onProgress(int current, int max) {
}
// Other Future methods just forwarded to computation
public boolean cancel(boolean mayInterruptIfRunning) {
return computation.cancel(mayInterruptIfRunning);
}
public V get() throws InterruptedException, ExecutionException {
return computation.get();
}
public V get(long timeout, TimeUnit unit)
throws InterruptedException,
ExecutionException,
TimeoutException {
return computation.get(timeout, unit);
}
public boolean isCancelled() {
return computation.isCancelled();
}
public boolean isDone() {
return computation.isDone();
}
public void run() {
computation.run();
}
}