FutureTaskWrapper for Java I did not like that get synchronizes every time I call it - because I may be calling it more than once. So I wrote the wrapper for the future interface which keeps not synchronized local variable for completion state and caches the result. I am very sure it is thread safe.
Please have a look:

package i;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class FutureTaskWrapper&lt;V&gt; implements RunnableFuture&lt;V&gt; {

    private FutureTask&lt;V&gt; localFuture;
    private V result;
    //this one is not synchronized on purpose. It does not have to be.
    //It will either use wrapped class' done mechanism or eventually will     update and it will use cached result.
    private boolean done = false;


    public FutureTaskWrapper(FutureTask&lt;V&gt; instance) {
        localFuture = instance;
    }

    @Override
    public void run() {
        localFuture.run();
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return localFuture.cancel(mayInterruptIfRunning);
    }

    @Override
    public boolean isCancelled() {
        return localFuture.isCancelled();
    }

    @Override
    public boolean isDone() {
        if (done) {
            return true;
        } else {
            return localFuture.isDone();
        }
    }

    @Override
    public V get() throws InterruptedException, ExecutionException {
        if (done) {
            System.out.println("using cached version.");
            return result;
        } else {
            System.out.println("using version version from future.");
            result = localFuture.get();
            done = true;
            return result;
        }
    }

    @Override
    public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        if (done) {
            System.out.println("using cached version.");
            return result;
        } else {
            System.out.println("using version version from future.");
            result = localFuture.get(timeout, unit);
            //could clean up localFuture here.
            done = true;
            return result;
        }
    }

    //main method for testing.
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        FutureTask&lt;String&gt; future = new FutureTask&lt;&gt;(() -&gt; {
            Thread.sleep(1000L);
            return "future";
        });
        FutureTaskWrapper&lt;String&gt; wrapper = new FutureTaskWrapper(future);
        executor.submit(future);
        wrapper.get();
        wrapper.get();
        wrapper.get();
        wrapper.get();

        executor.shutdownNow();
    }
}
I am very sure it is thread safe. 


Actually, it's not because the done is not in happens-before relations with the result.

But you can reach the desired behavior without extending anything: just check isDone() and call get() only if it was true.