/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain. Use, modify, and
* redistribute this code in any way without acknowledgement.
*/
package java.util.concurrent;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.*;
import java.util.concurrent.locks.*;
/**
* Provides default implementation of {@link ExecutorService}
* execution methods. This class implements the submit and
* invoke methods using the default {@link FutureTask} and
* {@link PrivilegedFutureTask} classes provided in this package. For
* example, the the implementation of submit(Runnable)
* creates an associated FutureTask that is executed and
* returned. Subclasses overriding these methods to use different
* {@link Future} implementations should do so consistently for each
* of these methods.
*
* @since 1.5
* @author Doug Lea
*/
public abstract class AbstractExecutorService implements ExecutorService {
public Future submit(Runnable task, T result) {
FutureTask ftask = new FutureTask(task, result);
execute(ftask);
return ftask;
}
public Future submit(Callable task) {
FutureTask ftask = new FutureTask(task);
execute(ftask);
return ftask;
}
public void invoke(Runnable task) throws ExecutionException, InterruptedException {
FutureTask> ftask = new FutureTask(task, Boolean.TRUE);
execute(ftask);
ftask.get();
}
public T invoke(Callable task) throws ExecutionException, InterruptedException {
FutureTask ftask = new FutureTask(task);
execute(ftask);
return ftask.get();
}
public Future submit(PrivilegedAction action) {
Callable task = new PrivilegedActionAdapter(action);
FutureTask future = new PrivilegedFutureTask(task);
execute(future);
return future;
}
public Future submit(PrivilegedExceptionAction action) {
Callable task = new PrivilegedExceptionActionAdapter(action);
FutureTask future = new PrivilegedFutureTask(task);
execute(future);
return future;
}
private static class PrivilegedActionAdapter implements Callable {
PrivilegedActionAdapter(PrivilegedAction action) {
this.action = action;
}
public Object call () {
return action.run();
}
private final PrivilegedAction action;
}
private static class PrivilegedExceptionActionAdapter implements Callable {
PrivilegedExceptionActionAdapter(PrivilegedExceptionAction action) {
this.action = action;
}
public Object call () throws Exception {
return action.run();
}
private final PrivilegedExceptionAction action;
}
// any/all methods, each a little bit different than the other
public T invokeAny(Collection> tasks)
throws InterruptedException, ExecutionException {
if (tasks == null)
throw new NullPointerException();
int n = tasks.size();
if (n == 0)
throw new IllegalArgumentException();
List> futures= new ArrayList>(n);
ExecutorCompletionService ecs =
new ExecutorCompletionService(this);
try {
for (Callable t : tasks)
futures.add(ecs.submit(t));
ExecutionException ee = null;
RuntimeException re = null;
while (n-- > 0) {
Future f = ecs.take();
try {
return f.get();
} catch(ExecutionException eex) {
ee = eex;
} catch(RuntimeException rex) {
re = rex;
}
}
if (ee != null)
throw ee;
if (re != null)
throw new ExecutionException(re);
throw new ExecutionException();
} finally {
for (Future f : futures)
f.cancel(true);
}
}
public T invokeAny(Collection> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (tasks == null || unit == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
int n = tasks.size();
if (n == 0)
throw new IllegalArgumentException();
List> futures= new ArrayList>(n);
ExecutorCompletionService ecs =
new ExecutorCompletionService(this);
try {
for (Callable t : tasks)
futures.add(ecs.submit(t));
ExecutionException ee = null;
RuntimeException re = null;
long lastTime = System.nanoTime();
while (n-- > 0) {
Future f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
try {
return f.get();
} catch(ExecutionException eex) {
ee = eex;
} catch(RuntimeException rex) {
re = rex;
}
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
if (ee != null)
throw ee;
if (re != null)
throw new ExecutionException(re);
throw new ExecutionException();
} finally {
for (Future f : futures)
f.cancel(true);
}
}
public T invokeAny(Collection tasks, T result)
throws InterruptedException, ExecutionException {
if (tasks == null)
throw new NullPointerException();
int n = tasks.size();
if (n == 0)
throw new IllegalArgumentException();
List> futures= new ArrayList>(n);
ExecutorCompletionService ecs =
new ExecutorCompletionService(this);
try {
for (Runnable t : tasks)
futures.add(ecs.submit(t, result));
ExecutionException ee = null;
RuntimeException re = null;
while (n-- > 0) {
Future f = ecs.take();
try {
return f.get();
} catch(ExecutionException eex) {
ee = eex;
} catch(RuntimeException rex) {
re = rex;
}
}
if (ee != null)
throw ee;
if (re != null)
throw new ExecutionException(re);
throw new ExecutionException();
} finally {
for (Future f : futures)
f.cancel(true);
}
}
public T invokeAny(Collection tasks, T result,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (tasks == null || unit == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
int n = tasks.size();
if (n == 0)
throw new IllegalArgumentException();
List> futures= new ArrayList>(n);
ExecutorCompletionService ecs =
new ExecutorCompletionService(this);
try {
for (Runnable t : tasks)
futures.add(ecs.submit(t, result));
ExecutionException ee = null;
RuntimeException re = null;
long lastTime = System.nanoTime();
while (n-- > 0) {
Future f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
if (f == null)
throw new TimeoutException();
try {
return f.get();
} catch(ExecutionException eex) {
ee = eex;
} catch(RuntimeException rex) {
re = rex;
}
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
if (ee != null)
throw ee;
if (re != null)
throw new ExecutionException(re);
throw new ExecutionException();
} finally {
for (Future f : futures)
f.cancel(true);
}
}
public List> invokeAll(Collection tasks, T result)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
List> futures = new ArrayList>(tasks.size());
boolean done = false;
try {
for (Runnable t : tasks) {
FutureTask f = new FutureTask(t, result);
futures.add(f);
execute(f);
}
for (Future f : futures) {
if (!f.isDone()) {
try {
f.get();
} catch(CancellationException ignore) {
} catch(ExecutionException ignore) {
}
}
}
done = true;
return futures;
} finally {
if (!done)
for (Future f : futures)
f.cancel(true);
}
}
public List> invokeAll(Collection tasks, T result,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null || unit == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
List> futures = new ArrayList>(tasks.size());
boolean done = false;
try {
for (Runnable t : tasks) {
FutureTask f = new FutureTask(t, result);
futures.add(f);
execute(f);
}
long lastTime = System.nanoTime();
for (Future f : futures) {
if (!f.isDone()) {
if (nanos < 0)
return futures;
try {
f.get(nanos, TimeUnit.NANOSECONDS);
} catch(CancellationException ignore) {
} catch(ExecutionException ignore) {
} catch(TimeoutException toe) {
return futures;
}
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
}
done = true;
return futures;
} finally {
if (!done)
for (Future f : futures)
f.cancel(true);
}
}
public List> invokeAll(Collection> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
List> futures = new ArrayList>(tasks.size());
boolean done = false;
try {
for (Callable t : tasks) {
FutureTask f = new FutureTask(t);
futures.add(f);
execute(f);
}
for (Future f : futures) {
if (!f.isDone()) {
try {
f.get();
} catch(CancellationException ignore) {
} catch(ExecutionException ignore) {
}
}
}
done = true;
return futures;
} finally {
if (!done)
for (Future f : futures)
f.cancel(true);
}
}
public List> invokeAll(Collection> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null || unit == null)
throw new NullPointerException();
long nanos = unit.toNanos(timeout);
List> futures = new ArrayList>(tasks.size());
boolean done = false;
try {
for (Callable t : tasks) {
FutureTask f = new FutureTask(t);
futures.add(f);
execute(f);
}
long lastTime = System.nanoTime();
for (Future f : futures) {
if (!f.isDone()) {
if (nanos < 0)
return futures;
try {
f.get(nanos, TimeUnit.NANOSECONDS);
} catch(CancellationException ignore) {
} catch(ExecutionException ignore) {
} catch(TimeoutException toe) {
return futures;
}
long now = System.nanoTime();
nanos -= now - lastTime;
lastTime = now;
}
}
done = true;
return futures;
} finally {
if (!done)
for (Future f : futures)
f.cancel(true);
}
}
}