View Javadoc
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 }