1 /*
2 * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
308 this.executor = executor;
309 this.task = task;
310 }
311 @Override
312 public void run() {
313 try {
314 task.run();
315 } finally {
316 executor.taskComplete(Thread.currentThread());
317 }
318 }
319 }
320
321 /**
322 * A Future for a task that runs in its own thread. The thread is
323 * created (but not started) when the Future is created. The thread
324 * is interrupted when the future is cancelled. The executor is
325 * notified when the task completes.
326 */
327 private static class ThreadBoundFuture<T>
328 extends CompletableFuture<T> implements Runnable {
329
330 final ThreadPerTaskExecutor executor;
331 final Callable<T> task;
332 final Thread thread;
333
334 ThreadBoundFuture(ThreadPerTaskExecutor executor, Callable<T> task) {
335 this.executor = executor;
336 this.task = task;
337 this.thread = executor.newThread(this);
338 }
339
340 Thread thread() {
341 return thread;
342 }
343
344 @Override
345 public void run() {
346 if (Thread.currentThread() != thread) {
347 // should not happen except where something casts this object
348 // to a Runnable and invokes the run method.
349 throw new WrongThreadException();
350 }
351 try {
352 T result = task.call();
353 complete(result);
354 } catch (Throwable e) {
355 completeExceptionally(e);
356 } finally {
357 executor.taskComplete(thread);
358 }
359 }
360
361 @Override
362 public boolean cancel(boolean mayInterruptIfRunning) {
363 boolean cancelled = super.cancel(mayInterruptIfRunning);
364 if (cancelled && mayInterruptIfRunning)
365 thread.interrupt();
366 return cancelled;
367 }
368 }
369
370 @Override
371 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
372 throws InterruptedException {
373
374 Objects.requireNonNull(tasks);
375 List<Future<T>> futures = new ArrayList<>();
376 int j = 0;
377 try {
378 for (Callable<T> t : tasks) {
379 Future<T> f = submit(t);
380 futures.add(f);
381 }
382 for (int size = futures.size(); j < size; j++) {
383 Future<T> f = futures.get(j);
384 if (!f.isDone()) {
385 try {
386 f.get();
|
1 /*
2 * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
308 this.executor = executor;
309 this.task = task;
310 }
311 @Override
312 public void run() {
313 try {
314 task.run();
315 } finally {
316 executor.taskComplete(Thread.currentThread());
317 }
318 }
319 }
320
321 /**
322 * A Future for a task that runs in its own thread. The thread is
323 * created (but not started) when the Future is created. The thread
324 * is interrupted when the future is cancelled. The executor is
325 * notified when the task completes.
326 */
327 private static class ThreadBoundFuture<T>
328 extends FutureTask<T> implements Runnable {
329
330 final ThreadPerTaskExecutor executor;
331 final Thread thread;
332
333 ThreadBoundFuture(ThreadPerTaskExecutor executor, Callable<T> task) {
334 super(task);
335 this.executor = executor;
336 this.thread = executor.newThread(this);
337 }
338
339 Thread thread() {
340 return thread;
341 }
342
343 @Override
344 protected void done() {
345 executor.taskComplete(thread);
346 }
347 }
348
349 @Override
350 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
351 throws InterruptedException {
352
353 Objects.requireNonNull(tasks);
354 List<Future<T>> futures = new ArrayList<>();
355 int j = 0;
356 try {
357 for (Callable<T> t : tasks) {
358 Future<T> f = submit(t);
359 futures.add(f);
360 }
361 for (int size = futures.size(); j < size; j++) {
362 Future<T> f = futures.get(j);
363 if (!f.isDone()) {
364 try {
365 f.get();
|