
net.darkmist.alib.job.CurrentThreadExecutor Maven / Gradle / Ivy
/*
* Copyright (C) 2012 Ed Schaller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.darkmist.alib.job;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/** A Executor that immedately executes in the current thread.
* In many respects this is a non-Executor
*/
public class CurrentThreadExecutor implements ExecutorService
{
private static final CurrentThreadExecutor singleton = new CurrentThreadExecutor();
/** Here in case you need it. Call @{link #instance}
* instead as you really only need one instance.
*/
public CurrentThreadExecutor()
{
}
/** Get singleton instance. */
public static CurrentThreadExecutor instance()
{
return singleton;
}
/** Execute cmd in the current thread immediately and
* return when done.
* @param cmd The Runnable to run.
*/
@Override
public void execute(Runnable cmd)
{
cmd.run();
}
/** Does nothing. */
@Override
public void shutdown()
{
}
/** Does nothing.
* @return A empty list.
*/
@Override
public List shutdownNow()
{
return Collections.emptyList();
}
/** Always true.
* @return true
*/
@Override
public boolean isShutdown()
{
return true;
}
/** Always true.
* @return true
*/
@Override
public boolean isTerminated()
{
return true;
}
/** Always immediately true.
* @param timeout unused
* @param unit unused
* @return true
*/
@Override
public boolean awaitTermination(@SuppressWarnings("unused") long timeout, @SuppressWarnings("unused") TimeUnit unit)
{
return true;
}
protected Future run(Callable task)
{
T result = null;
Exception exception = null;
try
{
result = task.call();
}
catch(Exception e)
{
exception = e;
}
return new Past(result, exception);
}
protected Future run(Runnable task, T result)
{
return run(Executors.callable(task, result));
}
protected Future> run(Runnable task)
{
return run(Executors.callable(task));
}
/** Submit a @{link Callable} task and execute it immediately.
* @param task The task to run
* @return A @{link Past} containing the result.
*/
@Override
public Future submit(Callable task)
{
return run(task);
}
/** Submit a @{link Runnable} task and execute it immediately.
* @param task The task to run
* @param result The result the @{link Past} returns.
* @return A @{link Past} containing the result.
*/
@Override
public Future submit(Runnable task, T result)
{
return run(task, result);
}
/** Submit a @{link Runnable} task and execute it immediately.
* @param task The task to run
* @return A @{link Past} containing the result.
*/
@Override
public Future> submit(Runnable task)
{
return run(task);
}
@Override
public List> invokeAll(Collection extends Callable> tasks) throws InterruptedException
{
List> results = new ArrayList>(tasks.size());
for(Callable task : tasks)
results.add(run(task));
return results;
}
/** Implements @{link Executorservice#InvokeAll(Collection, long, TimeUnit)} by executing each task sequentially in the current thread until all are finished or the timeout has occured. The timeout is NOT at all percise. The current time in milliseconds is chcekced against the timout before each task is run. This has the potential of returning the longest task execution time after the timeout occurs in the worst case. */
@Override
public List> invokeAll(Collection extends Callable> tasks, long timeout, TimeUnit unit) throws InterruptedException
{
long end = System.currentTimeMillis() + unit.toMillis(timeout);
List> results = new ArrayList>(tasks.size());
Iterator extends Callable> i = tasks.iterator();
while(System.currentTimeMillis() < end && i.hasNext())
results.add(run(i.next()));
return results;
}
@Override
public T invokeAny(Collection extends Callable> tasks) throws InterruptedException, ExecutionException
{
ExecutionException last = null;
if(tasks.size() <= 0)
throw new IllegalArgumentException("Empty tasks passed.");
for(Callable task: tasks)
try
{
return run(task).get();
}
catch(ExecutionException e)
{
last = e;
}
if(last != null)
throw last;
throw new IllegalStateException("No task finished and no task threw an exception.");
}
@Override
public T invokeAny(Collection extends Callable> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException
{
long end = System.currentTimeMillis() + unit.toMillis(timeout);
Iterator extends Callable> i = tasks.iterator();
ExecutionException last = null;
if(tasks.size() <= 0)
throw new IllegalArgumentException("Empty tasks passed.");
while(System.currentTimeMillis() < end && i.hasNext())
try
{
return run(i.next()).get();
}
catch(ExecutionException e)
{
last = e;
}
if(last != null)
throw last;
throw new IllegalStateException("No task finished and no task threw an exception.");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy