![JAR search and dependency download from the Maven repository](/logo.png)
javadoc.src-html.com.google.common.util.concurrent.Uninterruptibles.html Maven / Gradle / Ivy
The newest version!
001 /*
002 * Copyright (C) 2011 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package com.google.common.util.concurrent;
018
019 import static java.util.concurrent.TimeUnit.NANOSECONDS;
020
021 import com.google.common.annotations.Beta;
022 import com.google.common.base.Preconditions;
023
024 import java.util.concurrent.BlockingQueue;
025 import java.util.concurrent.CountDownLatch;
026 import java.util.concurrent.ExecutionException;
027 import java.util.concurrent.Future;
028 import java.util.concurrent.TimeUnit;
029 import java.util.concurrent.TimeoutException;
030
031 /**
032 * Utilities for treating interruptible operations as uninterruptible.
033 * In all cases, if a thread is interrupted during such a call, the call
034 * continues to block until the result is available or the timeout elapses,
035 * and only then re-interrupts the thread.
036 *
037 * @author Anthony Zana
038 * @since 10.0
039 */
040 @Beta
041 public final class Uninterruptibles {
042
043 // Implementation Note: As of 3-7-11, the logic for each blocking/timeout
044 // methods is identical, save for method being invoked.
045
046 /**
047 * Invokes {@code latch.}{@link CountDownLatch#await() await()}
048 * uninterruptibly.
049 */
050 public static void awaitUninterruptibly(CountDownLatch latch) {
051 boolean interrupted = false;
052 try {
053 while (true) {
054 try {
055 latch.await();
056 return;
057 } catch (InterruptedException e) {
058 interrupted = true;
059 }
060 }
061 } finally {
062 if (interrupted) {
063 Thread.currentThread().interrupt();
064 }
065 }
066 }
067
068 /**
069 * Invokes
070 * {@code latch.}{@link CountDownLatch#await(long, TimeUnit)
071 * await(timeout, unit)} uninterruptibly.
072 */
073 public static boolean awaitUninterruptibly(CountDownLatch latch,
074 long timeout, TimeUnit unit) {
075 boolean interrupted = false;
076 try {
077 long remainingNanos = unit.toNanos(timeout);
078 long end = System.nanoTime() + remainingNanos;
079
080 while (true) {
081 try {
082 // CountDownLatch treats negative timeouts just like zero.
083 return latch.await(remainingNanos, NANOSECONDS);
084 } catch (InterruptedException e) {
085 interrupted = true;
086 remainingNanos = end - System.nanoTime();
087 }
088 }
089 } finally {
090 if (interrupted) {
091 Thread.currentThread().interrupt();
092 }
093 }
094 }
095
096 /**
097 * Invokes {@code toJoin.}{@link Thread#join() join()} uninterruptibly.
098 */
099 public static void joinUninterruptibly(Thread toJoin) {
100 boolean interrupted = false;
101 try {
102 while (true) {
103 try {
104 toJoin.join();
105 return;
106 } catch (InterruptedException e) {
107 interrupted = true;
108 }
109 }
110 } finally {
111 if (interrupted) {
112 Thread.currentThread().interrupt();
113 }
114 }
115 }
116
117 /**
118 * Invokes {@code future.}{@link Future#get() get()} uninterruptibly.
119 * To get uninterruptibility and remove checked exceptions, see
120 * {@link Futures#getUnchecked}.
121 *
122 * <p>If instead, you wish to treat {@link InterruptedException} uniformly
123 * with other exceptions, see {@link Futures#get(Future, Class) Futures.get}
124 * or {@link Futures#makeChecked}.
125 */
126 public static <V> V getUninterruptibly(Future<V> future)
127 throws ExecutionException {
128 boolean interrupted = false;
129 try {
130 while (true) {
131 try {
132 return future.get();
133 } catch (InterruptedException e) {
134 interrupted = true;
135 }
136 }
137 } finally {
138 if (interrupted) {
139 Thread.currentThread().interrupt();
140 }
141 }
142 }
143
144 /**
145 * Invokes
146 * {@code future.}{@link Future#get(long, TimeUnit) get(timeout, unit)}
147 * uninterruptibly.
148 *
149 * <p>If instead, you wish to treat {@link InterruptedException} uniformly
150 * with other exceptions, see {@link Futures#get(Future, Class) Futures.get}
151 * or {@link Futures#makeChecked}.
152 */
153 public static <V> V getUninterruptibly(
154 Future<V> future, long timeout, TimeUnit unit)
155 throws ExecutionException, TimeoutException {
156 boolean interrupted = false;
157 try {
158 long remainingNanos = unit.toNanos(timeout);
159 long end = System.nanoTime() + remainingNanos;
160
161 while (true) {
162 try {
163 // Future treats negative timeouts just like zero.
164 return future.get(remainingNanos, NANOSECONDS);
165 } catch (InterruptedException e) {
166 interrupted = true;
167 remainingNanos = end - System.nanoTime();
168 }
169 }
170 } finally {
171 if (interrupted) {
172 Thread.currentThread().interrupt();
173 }
174 }
175 }
176
177 /**
178 * Invokes
179 * {@code unit.}{@link TimeUnit#timedJoin(Thread, long)
180 * timedJoin(toJoin, timeout)} uninterruptibly.
181 */
182 public static void joinUninterruptibly(Thread toJoin,
183 long timeout, TimeUnit unit) {
184 Preconditions.checkNotNull(toJoin);
185 boolean interrupted = false;
186 try {
187 long remainingNanos = unit.toNanos(timeout);
188 long end = System.nanoTime() + remainingNanos;
189 while (true) {
190 try {
191 // TimeUnit.timedJoin() treats negative timeouts just like zero.
192 NANOSECONDS.timedJoin(toJoin, remainingNanos);
193 return;
194 } catch (InterruptedException e) {
195 interrupted = true;
196 remainingNanos = end - System.nanoTime();
197 }
198 }
199 } finally {
200 if (interrupted) {
201 Thread.currentThread().interrupt();
202 }
203 }
204 }
205
206 /**
207 * Invokes {@code queue.}{@link BlockingQueue#take() take()} uninterruptibly.
208 */
209 public static <E> E takeUninterruptibly(BlockingQueue<E> queue) {
210 boolean interrupted = false;
211 try {
212 while (true) {
213 try {
214 return queue.take();
215 } catch (InterruptedException e) {
216 interrupted = true;
217 }
218 }
219 } finally {
220 if (interrupted) {
221 Thread.currentThread().interrupt();
222 }
223 }
224 }
225
226 /**
227 * Invokes {@code queue.}{@link BlockingQueue#put(Object) put(element)}
228 * uninterruptibly.
229 */
230 public static <E> void putUninterruptibly(BlockingQueue<E> queue, E element) {
231 boolean interrupted = false;
232 try {
233 while (true) {
234 try {
235 queue.put(element);
236 return;
237 } catch (InterruptedException e) {
238 interrupted = true;
239 }
240 }
241 } finally {
242 if (interrupted) {
243 Thread.currentThread().interrupt();
244 }
245 }
246 }
247
248 // TODO(user): Support Sleeper somehow (wrapper or interface method)?
249 /**
250 * Invokes {@code unit.}{@link TimeUnit#sleep(long) sleep(sleepFor)}
251 * uninterruptibly.
252 */
253 public static void sleepUninterruptibly(long sleepFor, TimeUnit unit) {
254 boolean interrupted = false;
255 try {
256 long remainingNanos = unit.toNanos(sleepFor);
257 long end = System.nanoTime() + remainingNanos;
258 while (true) {
259 try {
260 // TimeUnit.sleep() treats negative timeouts just like zero.
261 NANOSECONDS.sleep(remainingNanos);
262 return;
263 } catch (InterruptedException e) {
264 interrupted = true;
265 remainingNanos = end - System.nanoTime();
266 }
267 }
268 } finally {
269 if (interrupted) {
270 Thread.currentThread().interrupt();
271 }
272 }
273 }
274
275 // TODO(user): Add support for waitUninterruptibly.
276
277 private Uninterruptibles() {}
278 }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy