All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.threadly.concurrent.future.ExecuteOnGetFutureTask Maven / Gradle / Ivy

package org.threadly.concurrent.future;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * This future task has a special ability to start execution in the thread requesting the 
 * {@link #get()} IF it has not already started.  It is still expected that this future will be 
 * provided to an executor, but if that executor has been unable to start execution by the time 
 * {@link #get()} is requested, execution will start on the {@link #get()} thread.
 * 

* This can make sense if for example you need to have the result of a given future before you can * go forward with additional work. That way if the thread pool is too busy with other things, we * can try to get the result for this work unit as fast as possible (once we are ready for it). * If execution starts on the {@link #get()} call, once the task is started in the thread pool, it * will return immediately (WITHOUT invoking the task contained in the future). *

* This does come with some details to be aware of. Execution may only occur on the * {@link #get()} request. Requesting {@link #get(long, java.util.concurrent.TimeUnit)} will NOT * cause execution to start (as we can not ensure a timeout will be respected). In addition this * can not work with recurring tasks. * * @since 2.4.0 * @param The result object type returned by this future */ public class ExecuteOnGetFutureTask extends ListenableFutureTask { private final AtomicBoolean executionStarted = new AtomicBoolean(false); /** * Constructs a runnable future with a runnable work unit. * * @param task runnable to be run */ public ExecuteOnGetFutureTask(Runnable task) { super(task); } /** * Constructs a runnable future with a runnable work unit. * * @param task runnable to be run * @param result result to be provide after run has completed */ public ExecuteOnGetFutureTask(Runnable task, T result) { super(task, result); } /** * Constructs a runnable future with a callable work unit. * * @param task callable to be run */ public ExecuteOnGetFutureTask(Callable task) { super(task); } /** * Starts execution of task if it has not already started. This is thread safe, and will ensure * that execution will only occur once. */ protected void executeIfNotStarted() { if (! executionStarted.getPlain() && executionStarted.compareAndSet(false, true)) { super.run(); } } @Override public void run() { executeIfNotStarted(); } @Override public T get() throws InterruptedException, ExecutionException { executeIfNotStarted(); return super.get(); } @Override public Throwable getFailure() throws InterruptedException { executeIfNotStarted(); return super.getFailure(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy