Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (C) 2012 Ness Computing, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.opentable.concurrent;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Helper methods for ExecutorServices.
*/
public final class OTExecutors
{
private static final Logger LOG = LoggerFactory.getLogger(OTExecutors.class);
private OTExecutors() { }
/**
* Wrap an {@link ExecutorService} to make it appropriate for use in a
* try-with-resources block. The service is shutdown but may not be terminated
* by the end of the try statement.
*/
public static ShutdownExecutorService autoShutdown(ExecutorService service)
{
return new ShutdownExecutorService(service);
}
/**
* Wrap an {@link ExecutorService} to make it appropriate for use in a
* try-with-resources block. The service is terminated at the end of the
* try statement unless the timeout elapses, in which case a TimeoutException is thrown.
*/
public static TerminatingExecutorService autoTerminate(ExecutorService service, Duration timeout)
{
return new TerminatingExecutorService(service, timeout);
}
/**
* Wrap a {@link ScheduledExecutorService} to make it appropriate for use in a
* try-with-resources block. The service is shutdown but may not be terminated
* by the end of the try statement.
*/
public static ShutdownScheduledExecutorService autoShutdown(ScheduledExecutorService service)
{
return new ShutdownScheduledExecutorService(service);
}
/**
* Wrap a {@link ScheduledExecutorService} to make it appropriate for use in a
* try-with-resources block. The service is terminated at the end of the
* try statement unless the timeout elapses, in which case a TimeoutException is thrown.
*/
public static TerminatingScheduledExecutorService autoTerminate(ScheduledExecutorService service, Duration timeout)
{
return new TerminatingScheduledExecutorService(service, timeout);
}
/**
* Invoke all of the given callables. If they all succeed, returns a list of the futures. All will be
* {@link Future#isDone()}. If any fails, returns the list of Futures that succeeded before the failure, and
* the final future that caused the computation to fail. The remaining futures will be cancelled.
* If the calling thread is interrupted, it will make a best-effort attempt to cancel running tasks.
*/
public static List> invokeAllExplosively(ExecutorService service, Collection extends Callable> tasks)
throws InterruptedException
{
final ExecutorCompletionService completionService = new ExecutorCompletionService<>(service);
final ImmutableList.Builder> results = ImmutableList.builder();
final Set> inFlight = Sets.newHashSetWithExpectedSize(tasks.size());
boolean interrupted = false;
for (Callable task : tasks) {
inFlight.add(completionService.submit(task));
}
while (!inFlight.isEmpty()) {
final Future future;
try {
future = completionService.take();
} catch (InterruptedException e) {
interrupted = true;
break;
}
inFlight.remove(future);
results.add(future);
try {
future.get();
} catch (InterruptedException e) {
interrupted = true;
break;
} catch (ExecutionException e) {
break;
}
}
for (final Future future : inFlight) {
future.cancel(true);
}
if (interrupted) {
throw new InterruptedException();
}
return results.build();
}
/**
* Initiates shutdown and blocks until all tasks have completed execution, or the timeout occurs, or the current
* thread is interrupted, whichever happens first. {@code shutdown} is first called, and if the executor times
* out awaiting termination, {@code shutdownNow} is called, after which
* {@link #shutdownAndAwaitTermination(ExecutorService, Duration) shutdownAndAwaitTermination} again awaits
* termination. Note that the same timeout is used when waiting for shutdown after each shutdown command, so this
* call can potentially block for twice the given timeout. If the thread is interrupted before termination
* completes, the executor service is again instructed to {@code shutdownNow} and the interrupt status is
* preserved.
*
* This method implementation is inspired by the ExecutorService documentation example.
*
* @param pool the executor service to shut down
* @param timeout the amount of time to wait after shutdown
* @return true if the executor service terminated and false if the timeout elapsed before termination
* @throws InterruptedException if the thread is interrupted while waiting for shutdown
*/
public static boolean shutdownAndAwaitTermination(final ExecutorService pool, final Duration timeout)
throws InterruptedException {
final Instant start = Instant.now();
try {
final TimeUnit unit = TimeUnit.NANOSECONDS;
final long nanos = timeout.toNanos();
pool.shutdown();
try {
if (pool.awaitTermination(nanos, unit)) {
return true;
}
} catch (InterruptedException e) {
pool.shutdownNow();
throw e;
}
LOG.warn("{} shutdown failed; calling shutdownNow and waiting again", pool);
pool.shutdownNow();
pool.awaitTermination(nanos, unit);
return false;
} finally {
LOG.info("{} shutdown spent {}", pool, Duration.between(start, Instant.now()));
}
}
/**
* Alternate interface to {@link #shutdownAndAwaitTermination(ExecutorService, Duration)} that takes the old-school
* timeout long and TimeUnit parameters instead of a Duration.
* @param pool the executor service to shut down
* @param timeout the amount of time to wait after shutdown
* @param unit the time unit of the timeout argument
* @return true if the executor service terminated and false if the timeout elapsed before termination
* @throws InterruptedException if the thread is interrupted while waiting for shutdown
*/
public static boolean shutdownAndAwaitTermination(final ExecutorService pool, final long timeout, final TimeUnit unit)
throws InterruptedException {
final Duration timeoutDuration = Duration.ofNanos(unit.toNanos(timeout));
return shutdownAndAwaitTermination(pool, timeoutDuration);
}
}