Coverage Summary for Class: TestingExecutors (com.google.common.util.concurrent.testing)
| Class | Method, % | Line, % |
|---|---|---|
| TestingExecutors | 66.7% (2/3) | 66.7% (2/3) |
| TestingExecutors$NoOpScheduledExecutorService | 54.5% (6/11) | 53.8% (7/13) |
| TestingExecutors$NoOpScheduledExecutorService$NeverScheduledFuture | 50% (2/4) | 50% (2/4) |
| Total | 55.6% (10/18) | 55% (11/20) |
1 /* 2 * Copyright (C) 2012 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.util.concurrent.testing; 18 19 import com.google.common.annotations.Beta; 20 import com.google.common.annotations.GwtIncompatible; 21 import com.google.common.collect.ImmutableList; 22 import com.google.common.primitives.Longs; 23 import com.google.common.util.concurrent.AbstractFuture; 24 import com.google.common.util.concurrent.AbstractListeningExecutorService; 25 import com.google.common.util.concurrent.ListenableScheduledFuture; 26 import com.google.common.util.concurrent.ListeningScheduledExecutorService; 27 import com.google.common.util.concurrent.MoreExecutors; 28 import java.util.List; 29 import java.util.concurrent.Callable; 30 import java.util.concurrent.Delayed; 31 import java.util.concurrent.ScheduledFuture; 32 import java.util.concurrent.TimeUnit; 33 34 /** 35 * Factory methods for {@link ExecutorService} for testing. 36 * 37 * @author Chris Nokleberg 38 * @since 14.0 39 */ 40 @Beta 41 @GwtIncompatible 42 public final class TestingExecutors { 43 private TestingExecutors() {} 44 45 /** 46 * Returns a {@link ScheduledExecutorService} that never executes anything. 47 * 48 * <p>The {@code shutdownNow} method of the returned executor always returns an empty list despite 49 * the fact that everything is still technically awaiting execution. The {@code getDelay} method 50 * of any {@link ScheduledFuture} returned by the executor will always return the max long value 51 * instead of the time until the user-specified delay. 52 */ 53 public static ListeningScheduledExecutorService noOpScheduledExecutor() { 54 return new NoOpScheduledExecutorService(); 55 } 56 57 /** 58 * Creates a scheduled executor service that runs each task in the thread that invokes {@code 59 * execute/submit/schedule}, as in {@link CallerRunsPolicy}. This applies both to individually 60 * submitted tasks and to collections of tasks submitted via {@code invokeAll}, {@code invokeAny}, 61 * {@code schedule}, {@code scheduleAtFixedRate}, and {@code scheduleWithFixedDelay}. In the case 62 * of tasks submitted by {@code invokeAll} or {@code invokeAny}, tasks will run serially on the 63 * calling thread. Tasks are run to completion before a {@code Future} is returned to the caller 64 * (unless the executor has been shutdown). 65 * 66 * <p>The returned executor is backed by the executor returned by {@link 67 * MoreExecutors#newDirectExecutorService} and subject to the same constraints. 68 * 69 * <p>Although all tasks are immediately executed in the thread that submitted the task, this 70 * {@code ExecutorService} imposes a small locking overhead on each task submission in order to 71 * implement shutdown and termination behavior. 72 * 73 * <p>Because of the nature of single-thread execution, the methods {@code scheduleAtFixedRate} 74 * and {@code scheduleWithFixedDelay} are not supported by this class and will throw an 75 * UnsupportedOperationException. 76 * 77 * <p>The implementation deviates from the {@code ExecutorService} specification with regards to 78 * the {@code shutdownNow} method. First, "best-effort" with regards to canceling running tasks is 79 * implemented as "no-effort". No interrupts or other attempts are made to stop threads executing 80 * tasks. Second, the returned list will always be empty, as any submitted task is considered to 81 * have started execution. This applies also to tasks given to {@code invokeAll} or {@code 82 * invokeAny} which are pending serial execution, even the subset of the tasks that have not yet 83 * started execution. It is unclear from the {@code ExecutorService} specification if these should 84 * be included, and it's much easier to implement the interpretation that they not be. Finally, a 85 * call to {@code shutdown} or {@code shutdownNow} may result in concurrent calls to {@code 86 * invokeAll/invokeAny} throwing RejectedExecutionException, although a subset of the tasks may 87 * already have been executed. 88 * 89 * @since 15.0 90 */ 91 public static SameThreadScheduledExecutorService sameThreadScheduledExecutor() { 92 return new SameThreadScheduledExecutorService(); 93 } 94 95 private static final class NoOpScheduledExecutorService extends AbstractListeningExecutorService 96 implements ListeningScheduledExecutorService { 97 98 private volatile boolean shutdown; 99 100 @Override 101 public void shutdown() { 102 shutdown = true; 103 } 104 105 @Override 106 public List<Runnable> shutdownNow() { 107 shutdown(); 108 return ImmutableList.of(); 109 } 110 111 @Override 112 public boolean isShutdown() { 113 return shutdown; 114 } 115 116 @Override 117 public boolean isTerminated() { 118 return shutdown; 119 } 120 121 @Override 122 public boolean awaitTermination(long timeout, TimeUnit unit) { 123 return true; 124 } 125 126 @Override 127 public void execute(Runnable runnable) {} 128 129 @Override 130 public <V> ListenableScheduledFuture<V> schedule( 131 Callable<V> callable, long delay, TimeUnit unit) { 132 return NeverScheduledFuture.create(); 133 } 134 135 @Override 136 public ListenableScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { 137 return NeverScheduledFuture.create(); 138 } 139 140 @Override 141 public ListenableScheduledFuture<?> scheduleAtFixedRate( 142 Runnable command, long initialDelay, long period, TimeUnit unit) { 143 return NeverScheduledFuture.create(); 144 } 145 146 @Override 147 public ListenableScheduledFuture<?> scheduleWithFixedDelay( 148 Runnable command, long initialDelay, long delay, TimeUnit unit) { 149 return NeverScheduledFuture.create(); 150 } 151 152 private static class NeverScheduledFuture<V> extends AbstractFuture<V> 153 implements ListenableScheduledFuture<V> { 154 155 static <V> NeverScheduledFuture<V> create() { 156 return new NeverScheduledFuture<V>(); 157 } 158 159 @Override 160 public long getDelay(TimeUnit unit) { 161 return Long.MAX_VALUE; 162 } 163 164 @Override 165 public int compareTo(Delayed other) { 166 return Longs.compare(getDelay(TimeUnit.NANOSECONDS), other.getDelay(TimeUnit.NANOSECONDS)); 167 } 168 } 169 } 170 }