Class Timeout

  • All Implemented Interfaces:
    AutoCloseable

    public class Timeout
    extends Object
    implements AutoCloseable
    Timeout provides a mechanism for allowing a thread to interrupt itself if it doesn't return to a specific call site within a given timeout. Timeout instances are intended to be used with the try-with-resource pattern. Once constructed a Timeout attempts to ensure that the corresponding try-with-resource block completes within the specified timeout and if it does not the thread will self-interrupt. Exiting the timeout block will automatically clear any interrupt present on the thread and in such a case an InterruptedException will be thrown.
     try (Timeout t = Timeout.after(5, TimeUnit.SECONDS))
         {
         doSomething();
         } // this thread will self-interrupt if it doesn't reach this line within 5 seconds
     catch (InterruptedException e)
         {
         // thread timed out or was otherwise interrupted
         }
     
    In order for this to work any blocking code executed from within the context of the Timeout must use the Blocking static helper methods for blocking. An example of a compatible blocking call would be:
     void doSomething()
         {
         Object oField = m_oField;
         synchronized (oField)
             {
             Blocking.wait(oField); // rather then oField.wait();
             }
         }
     
    Note that Timeout can only self-interrupt at interruptible points, and does not defend against CPU bound loops for example.
    Author:
    mf 2015.02.23
    • Field Detail

      • f_fTloCreator

        protected final boolean f_fTloCreator
        True iff this Timeout created (and thus must ultimately destroy) the TLO.
      • f_mlTimeout

        protected final MutableLong f_mlTimeout
        Cached reference to the thread's MutableLong holding it's current timeout.
      • f_cMillisTimeout

        protected final long f_cMillisTimeout
        This Timeout's timeout.
      • f_lTimeoutOrig

        protected final long f_lTimeoutOrig
        The original timeout before this instance changed it.
      • s_tloTimeout

        protected static final ThreadLocal<MutableLong> s_tloTimeout
        A thread-local containing the calling thread's timeout value. Value which are greater or equal to zero are used to indicate timeout timestamps. Negative values are relative timeouts which haven't yet been realized into a timestamp. This allows for an optimization where we can avoid obtaining the current time when "setting" the timeout, and defer it until we are about to block.
    • Constructor Detail

      • Timeout

        protected Timeout​(long cMillis,
                          boolean fForceOverride)
        Specify a new timeout. This constructor variant allows the caller to override a parent timeout. This is rarely needed, and is roughly the equivalent of silently consuming a thread interrupt without rethrowing the InterruptedException.
        Parameters:
        cMillis - the new timeout.
        fForceOverride - true if this timeout is allowed to extend a parent timeout.
    • Method Detail

      • after

        public static Timeout after​(long time,
                                    TimeUnit unit)
        Specify a new timeout. Note that the calling thread's timeout will only be changed if the specified timeout is less then any existing timeout already active on the thread.
        Parameters:
        time - the new timeout
        unit - the unit the timeout is expressed in
        Returns:
        a Timeout instance to be used within a try-with-resource block
      • after

        public static Timeout after​(long cMillis)
        Specify a new timeout. Note that the calling thread's timeout will only be changed if the specified timeout is less then any existing timeout already active on the thread.
        Parameters:
        cMillis - the new timeout
        Returns:
        a Timeout instance to be used within a try-with-resource block
      • override

        public static Timeout override​(long cMillis)
        Specify a new timeout, potentially extending an already active timeout.

        This variant allows the caller to extend a parent timeout. This is rarely needed, and is roughly the equivalent of silently consuming a thread interrupt without rethrowing the InterruptedException. Use of this method should be extremely limited.

        Parameters:
        cMillis - the new timeout
        Returns:
        a Timeout instance to be used within a try-with-resource block
      • remainingTimeoutMillis

        public static long remainingTimeoutMillis()
        Return the number of milliseconds before this thread will timeout. Note if the current thread is timed out then invoking this method will also interrupt the thread. This method can be used to externally add Timeout support for other blocking APIs not covered by the existing Timeout helpers.
        Returns:
        the number of remaining milliseconds, 0 if timed out, or Long.MAX_VALUE if disabled.
      • isTimedOut

        public static boolean isTimedOut()
        Return true if the calling thread is timed out. Note if the current thread is timed out then invoking this method will also interrupt the thread. This method can be used to externally add Timeout support for other blocking APIs not covered by the existing Timeout helpers.
        Returns:
        true if the calling thread is timed out
      • isSet

        public static boolean isSet()
        Return true if calling thread specified a timeout.
        Returns:
        true if a timeout is set