code: public static void joinUntil(Clock clock, Thread thread, long endTime)
      throws InterruptedException, TimeoutException
    {
      if(endTime <= 0)
        thread.join();
      else
      {
        while(thread.isAlive())
        {
          long now = clock.currentTimeMillis();
          if(now >= endTime)
            throw new TimeoutException("timeout reached while joining on: " + thread);
          thread.join(endTime - now);
        }
      }
    }
docs: Joins on the thread but if end time is expired then throws an exception.
  
  @param thread the thread to join on
  @param endTime the time after which an exception is thrown (compared
  to {@link java.lang.System#currentTimeMillis()}. If &lt;= 0 then wait
  indefinitely (so <code>TimeOutException</code> will not be thrown!)
  @throws InterruptedException if the thread is interrupted while waiting
  @throws TimeoutException if the time has been reached