001/** 002 * Copyright 2010-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php 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 */ 016package org.kuali.common.util.base; 017 018import static com.google.common.base.Preconditions.checkState; 019import static java.util.concurrent.TimeUnit.MILLISECONDS; 020import static org.kuali.common.util.FormatUtils.getMillis; 021import static org.kuali.common.util.base.Exceptions.illegalState; 022 023import java.util.List; 024 025import com.google.common.base.Optional; 026import com.google.common.base.Stopwatch; 027 028public class Threads { 029 030 /** 031 * Check to make sure elapsed time on the stopwatch has not exceeded {@code timeout} and then sleep for the indicated number of milliseconds 032 * 033 * @throws IllegalStateException 034 * if elapsed time on the stopwatch has exceeded {@code timeout} or if {@code InterruptedException} is thrown while sleeping 035 * 036 * @returns The number of milliseconds this method slept for 037 */ 038 public static long checkedWait(Stopwatch sw, long timeout, long sleep) { 039 checkState(sw.elapsed(MILLISECONDS) <= timeout, "wait timeout exceeded"); 040 return sleep(sleep); 041 } 042 043 /** 044 * 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 045 * is approximate as the logic always assumes exactly 365 days a year. 046 * 047 * @throws <code>IllegalStateException</code> if interrupted. 048 */ 049 public static long sleep(String time) { 050 return sleep(getMillis(time)); 051 } 052 053 /** 054 * Sleep for <code>millis</code> or zero, if {@code !millis.isPresent()} 055 * 056 * @throws <code>IllegalStateException</code> if interrupted. 057 */ 058 public static long sleep(Optional<? extends Number> millis) { 059 if (millis.isPresent()) { 060 return sleep(millis.get().longValue()); 061 } else { 062 return 0; 063 } 064 } 065 066 /** 067 * Sleep for <code>millis</code> 068 * 069 * @throws <code>IllegalStateException</code> if interrupted. 070 */ 071 public static long sleep(long millis) { 072 try { 073 Thread.sleep(millis); 074 return millis; 075 } catch (InterruptedException e) { 076 throw illegalState(e); 077 } 078 } 079 080 /** 081 * Start each thread 082 */ 083 public static void start(List<Thread> threads) { 084 for (Thread thread : threads) { 085 thread.start(); 086 } 087 } 088 089 /** 090 * Invoke join() on each thread 091 * 092 * @throws <code>IllegalStateException</code> if any thread gets interrupted. 093 */ 094 public static void join(List<Thread> threads) { 095 for (Thread thread : threads) { 096 try { 097 thread.join(); 098 } catch (InterruptedException e) { 099 throw illegalState(e, "unexpected interruption [thread id:%s] [thread name:%s]", thread.getId(), thread.getName()); 100 } 101 } 102 } 103}