package org.threadly.concurrent;
import java.util.concurrent.Callable;
import org.threadly.concurrent.future.FutureUtils;
import org.threadly.concurrent.future.ListenableFuture;
import org.threadly.util.ArgumentVerifier;
import org.threadly.util.ExceptionUtils;
/**
* A {@link SubmitterExecutor} that will run all provided tasks immediately in the same thread
* that is calling into it. This is different from calling the runnable directly only in that no
* exceptions will propagate out. If an exception is thrown it will be provided to
* {@link ExceptionUtils#handleException(Throwable)} to In the case of just
* {@link #execute(Runnable)} thrown exceptions will be provided to
* {@link ExceptionUtils#handleException(Throwable)} to be handled. Otherwise thrown exceptions
* will be represented by their returned {@link ListenableFuture}.
*
* @since 1.2.0
*/
public class SameThreadSubmitterExecutor implements SubmitterExecutor {
private static final SameThreadSubmitterExecutor DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new SameThreadSubmitterExecutor();
}
/**
* Call to get a default instance of the {@link SameThreadSubmitterExecutor}. Because there is
* no saved or shared state, the same instance can be reused as much as desired.
*
* @return a static instance of SameThreadSubmitterExecutor
*/
public static SameThreadSubmitterExecutor instance() {
return DEFAULT_INSTANCE;
}
@Override
public void execute(Runnable task) {
ArgumentVerifier.assertNotNull(task, "task");
ExceptionUtils.runRunnable(task);
}
@Override
public ListenableFuture<?> submit(Runnable task) {
return submit(task, null);
}
@Override
public <T> ListenableFuture<T> submit(Runnable task, T result) {
ArgumentVerifier.assertNotNull(task, "task");
try {
task.run();
return FutureUtils.immediateResultFuture(result);
} catch (Throwable t) {
return FutureUtils.immediateFailureFuture(t);
}
}
@Override
public <T> ListenableFuture<T> submit(Callable<T> task) {
ArgumentVerifier.assertNotNull(task, "task");
try {
T result = task.call();
return FutureUtils.immediateResultFuture(result);
} catch (Throwable t) {
return FutureUtils.immediateFailureFuture(t);
}
}
}