1 /**
2 * Copyright 2010-2014 The Kuali Foundation
3 *
4 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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 package org.kuali.common.util.base;
17
18 import static com.google.common.base.Preconditions.checkState;
19 import static java.util.concurrent.TimeUnit.MILLISECONDS;
20 import static org.kuali.common.util.FormatUtils.getMillis;
21 import static org.kuali.common.util.base.Exceptions.illegalState;
22
23 import java.util.List;
24
25 import com.google.common.base.Optional;
26 import com.google.common.base.Stopwatch;
27
28 public class Threads {
29
30 /**
31 * Check to make sure elapsed time on the stopwatch has not exceeded {@code timeout} and then sleep for the indicated number of milliseconds
32 *
33 * @throws IllegalStateException
34 * if elapsed time on the stopwatch has exceeded {@code timeout} or if {@code InterruptedException} is thrown while sleeping
35 *
36 * @returns The number of milliseconds this method slept for
37 */
38 public static long checkedWait(Stopwatch sw, long timeout, long sleep) {
39 checkState(sw.elapsed(MILLISECONDS) <= timeout, "wait timeout exceeded");
40 return sleep(sleep);
41 }
42
43 /**
44 * Sleep for {@code time} where time is in the format 15ms, 15s, 15m, 15h, 15d, 15y for 15 milliseconds, seconds, minutes, hours, days, and years, respectively. Note that years
45 * is approximate as the logic always assumes exactly 365 days a year.
46 *
47 * @throws <code>IllegalStateException</code> if interrupted.
48 */
49 public static long sleep(String time) {
50 return sleep(getMillis(time));
51 }
52
53 /**
54 * Sleep for <code>millis</code> or zero, if {@code !millis.isPresent()}
55 *
56 * @throws <code>IllegalStateException</code> if interrupted.
57 */
58 public static long sleep(Optional<? extends Number> millis) {
59 if (millis.isPresent()) {
60 return sleep(millis.get().longValue());
61 } else {
62 return 0;
63 }
64 }
65
66 /**
67 * Sleep for <code>millis</code>
68 *
69 * @throws <code>IllegalStateException</code> if interrupted.
70 */
71 public static long sleep(long millis) {
72 try {
73 Thread.sleep(millis);
74 return millis;
75 } catch (InterruptedException e) {
76 throw illegalState(e);
77 }
78 }
79
80 /**
81 * Start each thread
82 */
83 public static void start(List<Thread> threads) {
84 for (Thread thread : threads) {
85 thread.start();
86 }
87 }
88
89 /**
90 * Invoke join() on each thread
91 *
92 * @throws <code>IllegalStateException</code> if any thread gets interrupted.
93 */
94 public static void join(List<Thread> threads) {
95 for (Thread thread : threads) {
96 try {
97 thread.join();
98 } catch (InterruptedException e) {
99 throw illegalState(e, "unexpected interruption [thread id:%s] [thread name:%s]", thread.getId(), thread.getName());
100 }
101 }
102 }
103 }