32 |
|
/** |
33 |
|
* A wrapper class that exposes only the ExecutorService methods |
34 |
|
* of an implementation. |
35 |
< |
*/ |
35 |
> |
*/ |
36 |
|
static private class DelegatedExecutorService implements ExecutorService { |
37 |
|
private final ExecutorService e; |
38 |
|
DelegatedExecutorService(ExecutorService executor) { e = executor; } |
91 |
|
*/ |
92 |
|
public static ExecutorService newSingleThreadExecutor() { |
93 |
|
return new DelegatedExecutorService |
94 |
< |
(new ThreadPoolExecutor(1, 1, |
94 |
> |
(new ThreadPoolExecutor(1, 1, |
95 |
|
0L, TimeUnit.MILLISECONDS, |
96 |
|
new LinkedBlockingQueue<Runnable>())); |
97 |
|
} |
107 |
|
*/ |
108 |
|
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { |
109 |
|
return new DelegatedExecutorService |
110 |
< |
(new ThreadPoolExecutor(1, 1, |
110 |
> |
(new ThreadPoolExecutor(1, 1, |
111 |
|
0L, TimeUnit.MILLISECONDS, |
112 |
|
new LinkedBlockingQueue<Runnable>(), |
113 |
|
threadFactory, null)); |
137 |
|
/** |
138 |
|
* Creates a thread pool that creates new threads as needed, but |
139 |
|
* will reuse previously constructed threads when they are |
140 |
< |
* available, and uses the provided |
140 |
> |
* available, and uses the provided |
141 |
|
* ThreadFactory to create new threads when needed. |
142 |
|
* @param threadfactory the factory to use when creating new threads |
143 |
|
* @return the newly created thread pool |
163 |
|
* for execution |
164 |
|
*/ |
165 |
|
public static <T> Future<T> execute(Executor executor, Runnable task, T value) { |
166 |
< |
FutureTask<T> ftask = new FutureTask<T>(task, value); |
166 |
> |
FutureTask<T> ftask; |
167 |
> |
if (executor instanceof ThreadPoolExecutor) { |
168 |
> |
ftask = new ThreadPoolFutureTask<T>( |
169 |
> |
(ThreadPoolExecutor) executor, task, value); |
170 |
> |
} else { |
171 |
> |
ftask = new FutureTask<T>(task, value); |
172 |
> |
} |
173 |
|
executor.execute(ftask); |
174 |
|
return ftask; |
175 |
|
} |
184 |
|
* @throws CannotExecuteException if task cannot be scheduled for execution |
185 |
|
*/ |
186 |
|
public static <T> FutureTask<T> execute(Executor executor, Callable<T> task) { |
187 |
< |
FutureTask<T> ftask = new FutureTask<T>(task); |
187 |
> |
FutureTask<T> ftask; |
188 |
> |
if (executor instanceof ThreadPoolExecutor) { |
189 |
> |
ftask = new ThreadPoolFutureTask<T>( |
190 |
> |
(ThreadPoolExecutor) executor, task); |
191 |
> |
} else { |
192 |
> |
ftask = new FutureTask<T>(task); |
193 |
> |
} |
194 |
|
executor.execute(ftask); |
195 |
|
return ftask; |
196 |
|
} |
225 |
|
executor.execute(ftask); |
226 |
|
return ftask.get(); |
227 |
|
} |
228 |
+ |
|
229 |
+ |
private static class ThreadPoolFutureTask<V> extends FutureTask<V> { |
230 |
+ |
|
231 |
+ |
ThreadPoolFutureTask(ThreadPoolExecutor tpe, Callable<V> callable) { |
232 |
+ |
super(callable); |
233 |
+ |
this.tpe = tpe; |
234 |
+ |
} |
235 |
+ |
|
236 |
+ |
ThreadPoolFutureTask(ThreadPoolExecutor tpe, Runnable runnable, V result) { |
237 |
+ |
super(runnable, result); |
238 |
+ |
this.tpe = tpe; |
239 |
+ |
} |
240 |
+ |
|
241 |
+ |
public boolean cancel(boolean mayInterruptIfRunning) { |
242 |
+ |
tpe.remove(this); // ignore success/failure |
243 |
+ |
return super.cancel(mayInterruptIfRunning); |
244 |
+ |
} |
245 |
+ |
|
246 |
+ |
private final ThreadPoolExecutor tpe; |
247 |
+ |
} |
248 |
|
} |