If you really want to keep the task to a single execution at a time, you should create a single threaded ThreadPool:
private ThreadPoolExecutor executor =
new ThreadPoolExecutor(1,1, 1, TimeUnit.SECONDS,
new SynchronousQueue(), new ThreadPoolExecutor.AbortPolicy());
private Future<Void> lastSubmitted;
private ReentrantLock submissionLock = new ReentrantLock();
...
try {
submissionLock.lock();
Future<Void> future =
executor.submit(new MyAsyncTask()); // assuming this implements Callable<Void>
lastSubmitted = future;
}
catch (RejectedExecutionException e) {
lastSubmitted.cancel();
Future<Void> future =
executor.submit(new MyAsyncTask()); // assuming this implements Callable<Void>
lastSubmitted = future;
}
finally {
submissionLock.unlock();
}
If you do it as suggested above, you'll get a RejectedExecutionException if you try to submit a task while one is already running. When that happens, you can cancel the last one submitted, and schedule a new execution. Keep in mind your task has to be interruptible (be careful with InputStream/OutputStream as they are not interruptible, use Channel objects instead).
The lock is needed so that you serialize the submission attempts. A thread could still get a RejectedExecutionException if another thread submitted a task during the catch block execution.