Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2007 The Guava Authors
   *
   * 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.google.common.util.concurrent;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 
 import java.util.List;
Factory and utility methods for java.util.concurrent.Executor, java.util.concurrent.ExecutorService, and java.util.concurrent.ThreadFactory.

Author(s):
Eric Fellheimer
Kyle Littlefield
Justin Mahoney
Since:
3.0
 
 public final class MoreExecutors {
   private MoreExecutors() {}

  
Converts the given ThreadPoolExecutor into an ExecutorService that exits when the application is complete. It does so by using daemon threads and adding a shutdown hook to wait for their completion.

This is mainly for fixed thread pools. See java.util.concurrent.Executors.newFixedThreadPool(int).

Parameters:
executor the executor to modify to make sure it exits when the application is finished
terminationTimeout how long to wait for the executor to finish before terminating the JVM
timeUnit unit of time for the time parameter
Returns:
an unmodifiable version of the input which will not hang the JVM
 
   @Beta
       ThreadPoolExecutor executorlong terminationTimeoutTimeUnit timeUnit) {
     return new Application()
         .getExitingExecutorService(executorterminationTimeouttimeUnit);
   }

  
Converts the given ScheduledThreadPoolExecutor into a ScheduledExecutorService that exits when the application is complete. It does so by using daemon threads and adding a shutdown hook to wait for their completion.

This is mainly for fixed thread pools. See java.util.concurrent.Executors.newScheduledThreadPool(int).

Parameters:
executor the executor to modify to make sure it exits when the application is finished
terminationTimeout how long to wait for the executor to finish before terminating the JVM
timeUnit unit of time for the time parameter
Returns:
an unmodifiable version of the input which will not hang the JVM
  @Beta
      ScheduledThreadPoolExecutor executorlong terminationTimeoutTimeUnit timeUnit) {
    return new Application()
        .getExitingScheduledExecutorService(executorterminationTimeouttimeUnit);
  }

  
Add a shutdown hook to wait for thread completion in the given service. This is useful if the given service uses daemon threads, and we want to keep the JVM from exiting immediately on shutdown, instead giving these daemon threads a chance to terminate normally.

Parameters:
service ExecutorService which uses daemon threads
terminationTimeout how long to wait for the executor to finish before terminating the JVM
timeUnit unit of time for the time parameter
  @Beta
  public static void addDelayedShutdownHook(
      ExecutorService servicelong terminationTimeoutTimeUnit timeUnit) {
    new Application()
        .addDelayedShutdownHook(serviceterminationTimeouttimeUnit);
  }

  
Converts the given ThreadPoolExecutor into an ExecutorService that exits when the application is complete. It does so by using daemon threads and adding a shutdown hook to wait for their completion.

This method waits 120 seconds before continuing with JVM termination, even if the executor has not finished its work.

This is mainly for fixed thread pools. See java.util.concurrent.Executors.newFixedThreadPool(int).

Parameters:
executor the executor to modify to make sure it exits when the application is finished
Returns:
an unmodifiable version of the input which will not hang the JVM
  @Beta
    return new Application().getExitingExecutorService(executor);
  }

  
Converts the given ThreadPoolExecutor into a ScheduledExecutorService that exits when the application is complete. It does so by using daemon threads and adding a shutdown hook to wait for their completion.

This method waits 120 seconds before continuing with JVM termination, even if the executor has not finished its work.

This is mainly for fixed thread pools. See java.util.concurrent.Executors.newScheduledThreadPool(int).

Parameters:
executor the executor to modify to make sure it exits when the application is finished
Returns:
an unmodifiable version of the input which will not hang the JVM
  @Beta
      ScheduledThreadPoolExecutor executor) {
    return new Application().getExitingScheduledExecutorService(executor);
  }

  
Represents the current application to register shutdown hooks.
  @VisibleForTesting static class Application {
        ThreadPoolExecutor executorlong terminationTimeoutTimeUnit timeUnit) {
      useDaemonThreadFactory(executor);
      ExecutorService service = Executors.unconfigurableExecutorService(executor);
      addDelayedShutdownHook(serviceterminationTimeouttimeUnit);
      return service;
    }
        ScheduledThreadPoolExecutor executorlong terminationTimeoutTimeUnit timeUnit) {
      useDaemonThreadFactory(executor);
      ScheduledExecutorService service = Executors.unconfigurableScheduledExecutorService(executor);
      addDelayedShutdownHook(serviceterminationTimeouttimeUnit);
      return service;
    }
    final void addDelayedShutdownHook(
        final ExecutorService servicefinal long terminationTimeoutfinal TimeUnit timeUnit) {
      checkNotNull(service);
      checkNotNull(timeUnit);
      addShutdownHook(MoreExecutors.newThread("DelayedShutdownHook-for-" + servicenew Runnable() {
        @Override
        public void run() {
          try {
            // We'd like to log progress and failures that may arise in the
            // following code, but unfortunately the behavior of logging
            // is undefined in shutdown hooks.
            // This is because the logging code installs a shutdown hook of its
            // own. See Cleaner class inside {@link LogManager}.
            service.shutdown();
            service.awaitTermination(terminationTimeouttimeUnit);
          } catch (InterruptedException ignored) {
            // We're shutting down anyway, so just ignore.
          }
        }
      }));
    }
      return getExitingExecutorService(executor, 120, .);
    }
        ScheduledThreadPoolExecutor executor) {
      return getExitingScheduledExecutorService(executor, 120, .);
    }
    @VisibleForTesting void addShutdownHook(Thread hook) {
      Runtime.getRuntime().addShutdownHook(hook);
    }
  }
  private static void useDaemonThreadFactory(ThreadPoolExecutor executor) {
        .setDaemon(true)
        .setThreadFactory(executor.getThreadFactory())
        .build());
  }

  
Creates an executor service that runs each task in the thread that invokes execute/submit, as in java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy This applies both to individually submitted tasks and to collections of tasks submitted via invokeAll or invokeAny. In the latter case, tasks will run serially on the calling thread. Tasks are run to completion before a Future is returned to the caller (unless the executor has been shutdown).

Although all tasks are immediately executed in the thread that submitted the task, this ExecutorService imposes a small locking overhead on each task submission in order to implement shutdown and termination behavior.

The implementation deviates from the ExecutorService specification with regards to the shutdownNow method. First, "best-effort" with regards to canceling running tasks is implemented as "no-effort". No interrupts or other attempts are made to stop threads executing tasks. Second, the returned list will always be empty, as any submitted task is considered to have started execution. This applies also to tasks given to invokeAll or invokeAny which are pending serial execution, even the subset of the tasks that have not yet started execution. It is unclear from the ExecutorService specification if these should be included, and it's much easier to implement the interpretation that they not be. Finally, a call to shutdown or shutdownNow may result in concurrent calls to invokeAll/invokeAny throwing RejectedExecutionException, although a subset of the tasks may already have been executed.

Since:
10.0 (mostly source-compatible since 3.0)
    return new SameThreadExecutorService();
  }
  // See sameThreadExecutor javadoc for behavioral notes.
  private static class SameThreadExecutorService
      extends AbstractListeningExecutorService {
    
Lock used whenever accessing the state variables (runningTasks, shutdown, terminationCondition) of the executor
    private final Lock lock = new ReentrantLock();

    
Signaled after the executor is shutdown and running tasks are done
    private final Condition termination = .newCondition();
    /*
     * Conceptually, these two variables describe the executor being in
     * one of three states:
     *   - Active: shutdown == false
     *   - Shutdown: runningTasks > 0 and shutdown == true
     *   - Terminated: runningTasks == 0 and shutdown == true
     */
    private int runningTasks = 0;
    private boolean shutdown = false;
    @Override
    public void execute(Runnable command) {
      startTask();
      try {
        command.run();
      } finally {
        endTask();
      }
    }
    @Override
    public boolean isShutdown() {
      .lock();
      try {
        return ;
      } finally {
        .unlock();
      }
    }
    @Override
    public void shutdown() {
      .lock();
      try {
         = true;
      } finally {
        .unlock();
      }
    }
    // See sameThreadExecutor javadoc for unusual behavior of this method.
    @Override
    public List<RunnableshutdownNow() {
      shutdown();
      return Collections.emptyList();
    }
    @Override
    public boolean isTerminated() {
      .lock();
      try {
        return  &&  == 0;
      } finally {
        .unlock();
      }
    }
    @Override
    public boolean awaitTermination(long timeoutTimeUnit unit)
        throws InterruptedException {
      long nanos = unit.toNanos(timeout);
      .lock();
      try {
        for (;;) {
          if (isTerminated()) {
            return true;
          } else if (nanos <= 0) {
            return false;
          } else {
            nanos = .awaitNanos(nanos);
          }
        }
      } finally {
        .unlock();
      }
    }

    
Checks if the executor has been shut down and increments the running task count.

Throws:
java.util.concurrent.RejectedExecutionException if the executor has been previously shutdown
    private void startTask() {
      .lock();
      try {
        if (isShutdown()) {
          throw new RejectedExecutionException("Executor already shutdown");
        }
        ++;
      } finally {
        .unlock();
      }
    }

    
Decrements the running task count.
    private void endTask() {
      .lock();
      try {
        --;
        if (isTerminated()) {
          .signalAll();
        }
      } finally {
        .unlock();
      }
    }
  }

  
Creates an java.util.concurrent.ExecutorService whose submit and invokeAll methods submit ListenableFutureTask instances to the given delegate executor. Those methods, as well as execute and invokeAny, are implemented in terms of calls to delegate.execute. All other methods are forwarded unchanged to the delegate. This implies that the returned ListeningExecutorService never calls the delegate's submit, invokeAll, and invokeAny methods, so any special handling of tasks must be implemented in the delegate's execute method or by wrapping the returned ListeningExecutorService.

If the delegate executor was already an instance of ListeningExecutorService, it is returned untouched, and the rest of this documentation does not apply.

Since:
10.0
      ExecutorService delegate) {
    return (delegate instanceof ListeningExecutorService)
        ? (ListeningExecutorServicedelegate
        : (delegate instanceof ScheduledExecutorService)
        ? new ScheduledListeningDecorator((ScheduledExecutorServicedelegate)
        : new ListeningDecorator(delegate);
  }

  
Creates a java.util.concurrent.ScheduledExecutorService whose submit and invokeAll methods submit ListenableFutureTask instances to the given delegate executor. Those methods, as well as execute and invokeAny, are implemented in terms of calls to delegate.execute. All other methods are forwarded unchanged to the delegate. This implies that the returned ListeningScheduledExecutorService never calls the delegate's submit, invokeAll, and invokeAny methods, so any special handling of tasks must be implemented in the delegate's execute method or by wrapping the returned ListeningScheduledExecutorService.

If the delegate executor was already an instance of ListeningScheduledExecutorService, it is returned untouched, and the rest of this documentation does not apply.

Since:
10.0
      ScheduledExecutorService delegate) {
    return (delegate instanceof ListeningScheduledExecutorService)
        ? (ListeningScheduledExecutorServicedelegate
        : new ScheduledListeningDecorator(delegate);
  }
  private static class ListeningDecorator
      extends AbstractListeningExecutorService {
    private final ExecutorService delegate;
      this. = checkNotNull(delegate);
    }
    @Override
    public boolean awaitTermination(long timeoutTimeUnit unit)
        throws InterruptedException {
      return .awaitTermination(timeoutunit);
    }
    @Override
    public boolean isShutdown() {
      return .isShutdown();
    }
    @Override
    public boolean isTerminated() {
      return .isTerminated();
    }
    @Override
    public void shutdown() {
      .shutdown();
    }
    @Override
    public List<RunnableshutdownNow() {
      return .shutdownNow();
    }
    @Override
    public void execute(Runnable command) {
      .execute(command);
    }
  }
  private static class ScheduledListeningDecorator
      extends ListeningDecorator implements ListeningScheduledExecutorService {
    @SuppressWarnings("hiding")
      super(delegate);
      this. = checkNotNull(delegate);
    }
    @Override
        Runnable commandlong delayTimeUnit unit) {
      ListenableFutureTask<Voidtask =
          ListenableFutureTask.create(commandnull);
      ScheduledFuture<?> scheduled = .schedule(taskdelayunit);
      return new ListenableScheduledTask<Void>(taskscheduled);
    }
    @Override
    public <V> ListenableScheduledFuture<V> schedule(
        Callable<V> callablelong delayTimeUnit unit) {
      ListenableFutureTask<V> task = ListenableFutureTask.create(callable);
      ScheduledFuture<?> scheduled = .schedule(taskdelayunit);
      return new ListenableScheduledTask<V>(taskscheduled);
    }
    @Override
        Runnable commandlong initialDelaylong periodTimeUnit unit) {
          new NeverSuccessfulListenableFutureTask(command);
      ScheduledFuture<?> scheduled =
          .scheduleAtFixedRate(taskinitialDelayperiodunit);
      return new ListenableScheduledTask<Void>(taskscheduled);
    }
    @Override
        Runnable commandlong initialDelaylong delayTimeUnit unit) {
          new NeverSuccessfulListenableFutureTask(command);
      ScheduledFuture<?> scheduled =
          .scheduleWithFixedDelay(taskinitialDelaydelayunit);
      return new ListenableScheduledTask<Void>(taskscheduled);
    }
    private static final class ListenableScheduledTask<V>
        extends SimpleForwardingListenableFuture<V>
        implements ListenableScheduledFuture<V> {
      private final ScheduledFuture<?> scheduledDelegate;
      public ListenableScheduledTask(
          ListenableFuture<V> listenableDelegate,
          ScheduledFuture<?> scheduledDelegate) {
        super(listenableDelegate);
        this. = scheduledDelegate;
      }
      @Override
      public boolean cancel(boolean mayInterruptIfRunning) {
        boolean cancelled = super.cancel(mayInterruptIfRunning);
        if (cancelled) {
          // Unless it is cancelled, the delegate may continue being scheduled
          .cancel(mayInterruptIfRunning);
          // TODO(user): Cancel "this" if "scheduledDelegate" is cancelled.
        }
        return cancelled;
      }
      @Override
      public long getDelay(TimeUnit unit) {
        return .getDelay(unit);
      }
      @Override
      public int compareTo(Delayed other) {
        return .compareTo(other);
      }
    }
    private static final class NeverSuccessfulListenableFutureTask
        extends AbstractFuture<Void>
        implements Runnable {
      private final Runnable delegate;
      public NeverSuccessfulListenableFutureTask(Runnable delegate) {
        this. = checkNotNull(delegate);
      }
      @Override public void run() {
        try {
          .run();
        } catch (Throwable t) {
          setException(t);
          throw Throwables.propagate(t);
        }
      }
    }
  }
  /*
   * This following method is a modified version of one found in
   * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/AbstractExecutorServiceTest.java?revision=1.30
   * which contained the following notice:
   *
   * Written by Doug Lea with assistance from members of JCP JSR-166
   * Expert Group and released to the public domain, as explained at
   * http://creativecommons.org/publicdomain/zero/1.0/
   * Other contributors include Andrew Wright, Jeffrey Hayes,
   * Pat Fisher, Mike Judd.
   */

  
 static <T> T invokeAnyImpl(ListeningExecutorService executorService,
      Collection<? extends Callable<T>> tasksboolean timedlong nanos)
    checkNotNull(executorService);
    int ntasks = tasks.size();
    checkArgument(ntasks > 0);
    List<Future<T>> futures = Lists.newArrayListWithCapacity(ntasks);
    BlockingQueue<Future<T>> futureQueue = Queues.newLinkedBlockingQueue();
    // For efficiency, especially in executors with limited
    // parallelism, check to see if previously submitted tasks are
    // done before submitting more of them. This interleaving
    // plus the exception mechanics account for messiness of main
    // loop.
    try {
      // Record exceptions so that if we fail to obtain any
      // result, we can throw the last exception we got.
      ExecutionException ee = null;
      long lastTime = timed ? System.nanoTime() : 0;
      Iterator<? extends Callable<T>> it = tasks.iterator();
      futures.add(submitAndAddQueueListener(executorServiceit.next(), futureQueue));
      --ntasks;
      int active = 1;
      for (;;) {
        Future<T> f = futureQueue.poll();
        if (f == null) {
          if (ntasks > 0) {
            --ntasks;
            futures.add(submitAndAddQueueListener(executorServiceit.next(), futureQueue));
            ++active;
          } else if (active == 0) {
            break;
          } else if (timed) {
            f = futureQueue.poll(nanos.);
            if (f == null) {
              throw new TimeoutException();
            }
            long now = System.nanoTime();
            nanos -= now - lastTime;
            lastTime = now;
          } else {
            f = futureQueue.take();
          }
        }
        if (f != null) {
          --active;
          try {
            return f.get();
          } catch (ExecutionException eex) {
            ee = eex;
          } catch (RuntimeException rex) {
            ee = new ExecutionException(rex);
          }
        }
      }
      if (ee == null) {
        ee = new ExecutionException(null);
      }
      throw ee;
    } finally {
      for (Future<T> f : futures) {
        f.cancel(true);
      }
    }
  }

  
Submits the task and adds a listener that adds the future to queue when it completes.
  private static <T> ListenableFuture<T> submitAndAddQueueListener(
      ListeningExecutorService executorServiceCallable<T> task,
      final BlockingQueue<Future<T>> queue) {
    final ListenableFuture<T> future = executorService.submit(task);
    future.addListener(new Runnable() {
      @Override public void run() {
        queue.add(future);
      }
    }, MoreExecutors.sameThreadExecutor());
    return future;
  }

  
Returns a default thread factory used to create new threads.

On AppEngine, returns ThreadManager.currentRequestThreadFactory(). Otherwise, returns java.util.concurrent.Executors.defaultThreadFactory().

Since:
14.0
  @Beta
  public static ThreadFactory platformThreadFactory() {
    if (!isAppEngine()) {
      return Executors.defaultThreadFactory();
    }
    try {
      return (ThreadFactory) Class.forName("com.google.appengine.api.ThreadManager")
          .getMethod("currentRequestThreadFactory")
          .invoke(null);
    } catch (IllegalAccessException e) {
      throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory"e);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory"e);
    } catch (NoSuchMethodException e) {
      throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory"e);
    } catch (InvocationTargetException e) {
      throw Throwables.propagate(e.getCause());
    }
  }
  private static boolean isAppEngine() {
    if (System.getProperty("com.google.appengine.runtime.environment") == null) {
      return false;
    }
    try {
      // If the current environment is null, we're not inside AppEngine.
      return Class.forName("com.google.apphosting.api.ApiProxy")
          .getMethod("getCurrentEnvironment")
          .invoke(null) != null;
    } catch (ClassNotFoundException e) {
      // If ApiProxy doesn't exist, we're not on AppEngine at all.
      return false;
    } catch (InvocationTargetException e) {
      // If ApiProxy throws an exception, we're not in a proper AppEngine environment.
      return false;
    } catch (IllegalAccessException e) {
      // If the method isn't accessible, we're not on a supported version of AppEngine;
      return false;
    } catch (NoSuchMethodException e) {
      // If the method doesn't exist, we're not on a supported version of AppEngine;
      return false;
    }
  }

  
Creates a thread using platformThreadFactory(), and sets its name to name unless changing the name is forbidden by the security manager.
  static Thread newThread(String nameRunnable runnable) {
    checkNotNull(name);
    checkNotNull(runnable);
    Thread result = platformThreadFactory().newThread(runnable);
    try {
      result.setName(name);
    } catch (SecurityException e) {
      // OK if we can't set the name in this environment.
    }
    return result;
  }
  // TODO(user): provide overloads for ListeningExecutorService? ListeningScheduledExecutorService?
  // TODO(user): provide overloads that take constant strings? Function<Runnable, String>s to
  // calculate names?

  
Creates an java.util.concurrent.Executor that renames the threads that its tasks run in.

The names are retrieved from the nameSupplier on the thread that is being renamed right before each task is run. The renaming is best effort, if a java.lang.SecurityManager prevents the renaming then it will be skipped but the tasks will still execute.

Parameters:
executor The executor to decorate
nameSupplier The source of names for each task
  static Executor renamingDecorator(final Executor executorfinal Supplier<StringnameSupplier) {
    checkNotNull(executor);
    checkNotNull(nameSupplier);
    if (isAppEngine()) {
      // AppEngine doesn't support thread renaming, so don't even try
      return executor;
    }
    return new Executor() {
      @Override public void execute(Runnable command) {
        executor.execute(Callables.threadRenaming(commandnameSupplier));
      }
    };
  }

  
Creates an java.util.concurrent.ExecutorService that renames the threads that its tasks run in.

The names are retrieved from the nameSupplier on the thread that is being renamed right before each task is run. The renaming is best effort, if a java.lang.SecurityManager prevents the renaming then it will be skipped but the tasks will still execute.

Parameters:
service The executor to decorate
nameSupplier The source of names for each task
      final Supplier<StringnameSupplier) {
    checkNotNull(service);
    checkNotNull(nameSupplier);
    if (isAppEngine()) {
      // AppEngine doesn't support thread renaming, so don't even try.
      return service;
    }
    return new WrappingExecutorService(service) {
      @Override protected <T> Callable<T> wrapTask(Callable<T> callable) {
        return Callables.threadRenaming(callablenameSupplier);
      }
      @Override protected Runnable wrapTask(Runnable command) {
        return Callables.threadRenaming(commandnameSupplier);
      }
    };
  }

  
Creates a java.util.concurrent.ScheduledExecutorService that renames the threads that its tasks run in.

The names are retrieved from the nameSupplier on the thread that is being renamed right before each task is run. The renaming is best effort, if a java.lang.SecurityManager prevents the renaming then it will be skipped but the tasks will still execute.

Parameters:
service The executor to decorate
nameSupplier The source of names for each task
      final Supplier<StringnameSupplier) {
    checkNotNull(service);
    checkNotNull(nameSupplier);
    if (isAppEngine()) {
      // AppEngine doesn't support thread renaming, so don't even try.
      return service;
    }
    return new WrappingScheduledExecutorService(service) {
      @Override protected <T> Callable<T> wrapTask(Callable<T> callable) {
        return Callables.threadRenaming(callablenameSupplier);
      }
      @Override protected Runnable wrapTask(Runnable command) {
        return Callables.threadRenaming(commandnameSupplier);
      }
    };
  }
New to GrepCode? Check out our FAQ X