synapse
synapse

Reputation: 5728

Executing two tasks consecutively

There's a thread pool with a single thread that is used to perform tasks submitted by multiple threads. The task is actually comprised of two parts - perform with meaningful result and cleanup that takes quite some time but returns no meaningful result. At the moment (obviously incorrect) implementation looks something like this. Is there an elegant way to ensure that another perform task will be executed only after previous cleanup task?

public class Main {
    private static class Worker {
        int perform() {
            return 1;
        }

        void cleanup() {
        }
    }

    private static void perform() throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(1);
        Worker w = new Worker();
        Future f = pool.submit(() -> w.perform());
        pool.submit(w::cleanup);
        int x = (int) f.get();
        System.out.println(x);
    }
}

Upvotes: 1

Views: 81

Answers (2)

Gray
Gray

Reputation: 116938

Is there an elegant way to ensure that another perform task will be executed only after previous cleanup task?

The most obvious thing to do is to call cleanup() from perform() but I assume there is a reason why you aren't doing that.

You say that your solution is currently "obviously incorrect". Why? Because of race conditions? Then you could add a synchronized block:

synchronized (pool) {
    Future f = pool.submit(() -> w.perform());
    pool.submit(w::cleanup);
}

That would ensure that the cleanup() would come immediately after a perform(). If you are worried about the performance hit with the synchronized, don't be.

Another solution might be to use the ExecutorCompletionService class although I'm not sure how that would help with one thread. I've used it before when I had cleanup tasks running in another thread pool.

Upvotes: 1

noscreenname
noscreenname

Reputation: 3370

If you are using java8, you can do this with CompletableFuture

CompletableFuture.supplyAsync(() -> w.perform(), pool)
    .thenApplyAsync(() -> w.cleanup(), pool)
    .join();

Upvotes: 1

Related Questions