У меня есть программка.
Это вспомогательная штука.
public class DaemonThreadFactory implements ThreadFactory {
/** Фабрика для создания потоков */
private final ThreadFactory fac = Executors.defaultThreadFactory();
/** Создает новый поток */
public Thread newThread(Runnable r) {
Thread result = fac.newThread(r);
result.setDaemon(true);
return result;
}
}
Вот основная программка.
public class FutureTaskTest {
public static void main(String[] args) throws Exception {
new FutureTaskTest().test();
}
private final ExecutorService executor =
Executors.newSingleThreadExecutor(new DaemonThreadFactory());
public void test() throws Exception {
Task task = new Task();
FutureTask<Void> future = new FutureTask<Void>(task);
task.setFuture(future);
executor.execute(future);
Thread.sleep(100);
future.cancel(true);
System.out.println("wait");
try {
future.get();
} catch(CancellationException ex) {
System.out.println("cancellation exception");
}
System.out.println("thinking task done");
Thread.sleep(1000);
}
}
class Task implements Callable<Void> {
private Future<Void> future;
public void setFuture(Future<Void> future) {
this.future = future;
}
public Void call() throws Exception {
while( !future.isCancelled() ) {
System.out.println("go");
try {
Thread.sleep(500);
} catch(InterruptedException ex) {
System.out.println("interrupted");
Thread.sleep(1000);
System.out.println("rrrrrrrrrrrr");
}
}
System.out.println("cancelled");
return null;
}
}
В методе test() запускаем задачу на выполнение, затем ее отменяем и пытаемся подождать завершения с помошью метода get(). Это не получается, так как метод get() не ждет завершения метода call() класса Task, а сразу генерирует исключение. В результате получаем на консоле следующее.
go
wait
cancellation exception
thinking task done
interrupted
rrrrrrrrrrrr
cancelled
То есть после thunking task done задача еще продолжает работать.
Я хочу чтобы при вызове get() или другого подобного метода, выполнение основного потока блокировалось пока не завершится задача работающая в фоне. Может быть какой-нибудь другой высокоуровневый примитив синхронизации можно применить (чтобы можно было cancel() использовать).
Мне это нужно что-бы последовательно выполнять задачи, но не начинать выполнение следующей задачи без отмены предыдущей.