Package jmri.util

Class ThreadingUtil

java.lang.Object
jmri.util.ThreadingUtil

@ThreadSafe
public class ThreadingUtil
extends Object
Utilities for handling JMRI's threading conventions.

For background, see http://jmri.org/help/en/html/doc/Technical/Threads.shtml

Note this distinguishes "on layout", for example, Setting a sensor, from "on GUI", for example, manipulating the Swing GUI. That may not be an important distinction now, but it might be later, so we build it into the calls.

  • Constructor Details

  • Method Details

    • runOnLayout

      public static void runOnLayout​(@Nonnull ThreadingUtil.ThreadAction ta)
      Run some layout-specific code before returning.

      Typical uses:

      ThreadingUtil.runOnLayout(() -> { sensor.setState(value); });

      Parameters:
      ta - What to run, usually as a lambda expression
    • runOnLayoutEventually

      Run some layout-specific code at some later point.

      Please note the operation may have happened before this returns. Or later. No long-term guarantees.

      Typical uses:

      ThreadingUtil.runOnLayoutEventually(() -> { sensor.setState(value); });

      Parameters:
      ta - What to run, usually as a lambda expression
    • runOnLayoutDelayed

      Run some layout-specific code at some later point, at least a known time in the future.

      There is no long-term guarantee about the accuracy of the interval.

      Typical uses:

      ThreadingUtil.runOnLayoutDelayed(() -> { sensor.setState(value); }, 1000);

      Parameters:
      ta - what to run, usually as a lambda expression
      delay - interval in milliseconds
      Returns:
      reference to timer object handling delay so you can cancel if desired; note that operation may have already taken place.
    • isLayoutThread

      public static boolean isLayoutThread()
      Check if on the layout-operation thread.
      Returns:
      true if on the layout-operation thread
    • runOnGUI

      public static void runOnGUI​(@Nonnull ThreadingUtil.ThreadAction ta)
      Run some GUI-specific code before returning

      Typical uses:

      ThreadingUtil.runOnGUI(() -> { mine.setVisible(); });

      If an InterruptedException is encountered, it'll be deferred to the next blocking call via Thread.currentThread().interrupt()

      Parameters:
      ta - What to run, usually as a lambda expression
    • runOnGUIwithReturn

      Run some GUI-specific code before returning a value.

      Typical uses:

      Boolean retval = ThreadingUtil.runOnGUIwithReturn(() -> { return mine.isVisible(); });

      If an InterruptedException is encountered, it'll be deferred to the next blocking call via Thread.currentThread().interrupt()

      Type Parameters:
      E - generic
      Parameters:
      ta - What to run, usually as a lambda expression
      Returns:
      the value returned by ta
    • runOnGUIEventually

      Run some GUI-specific code at some later point.

      If invoked from the GUI thread, the work is guaranteed to happen only after the current routine has returned.

      Typical uses:

      ThreadingUtil.runOnGUIEventually( ()->{ mine.setVisible(); } );

      Parameters:
      ta - What to run, usually as a lambda expression
    • runOnGUIDelayed

      Run some GUI-specific code at some later point, at least a known time in the future.

      There is no long-term guarantee about the accuracy of the interval.

      Typical uses:

      ThreadingUtil.runOnGUIDelayed( ()->{ mine.setVisible(); }, 1000);

      Parameters:
      ta - What to run, usually as a lambda expression
      delay - interval in milliseconds
      Returns:
      reference to timer object handling delay so you can cancel if desired; note that operation may have already taken place.
    • isGUIThread

      public static boolean isGUIThread()
      Check if on the GUI event dispatch thread.
      Returns:
      true if on the event dispatch thread
    • newThread

      public static Thread newThread​(Runnable runner)
      Create a new thread in the JMRI group
      Parameters:
      runner - Runnable.
      Returns:
      new Thread.
    • newThread

      public static Thread newThread​(Runnable runner, String name)
      Create a new thread in the JMRI group.
      Parameters:
      runner - Thread runnable.
      name - Thread name.
      Returns:
      New Thread.
    • getJmriThreadGroup

      Get the JMRI default thread group. This should be passed to as the first argument to the Thread constructor so we can track JMRI-created threads.
      Returns:
      JMRI default thread group.
    • canThreadRun

      public static boolean canThreadRun​(@Nonnull Thread t)
      Check whether a specific thread is running (or able to run) right now.
      Parameters:
      t - the thread to check
      Returns:
      true is the specified thread is or could be running right now
    • isThreadWaiting

      public static boolean isThreadWaiting​(@Nonnull Thread t)
      Check whether a specific thread is currently waiting.

      Note: This includes both waiting due to an explicit wait() call, and due to being blocked attempting to synchronize.

      Note: canThreadRun(Thread) and isThreadWaiting(Thread) should never simultaneously be true, but it might look that way due to sampling delays when checking on another thread.

      Parameters:
      t - the thread to check
      Returns:
      true is the specified thread is or could be running right now
    • requireGuiThread

      public static void requireGuiThread​(org.slf4j.Logger logger)
      Check that a call is on the GUI thread. Warns (once) if not. Intended to be the run-time check mechanism for @InvokeOnGuiThread

      In this implementation, this is the same as requireLayoutThread(org.slf4j.Logger)

      Parameters:
      logger - The logger object from the calling class, usually "log"
    • requireLayoutThread

      public static void requireLayoutThread​(org.slf4j.Logger logger)
      Check that a call is on the Layout thread. Warns (once) if not. Intended to be the run-time check mechanism for @InvokeOnLayoutThread

      In this implementation, this is the same as requireGuiThread(org.slf4j.Logger)

      Parameters:
      logger - The logger object from the calling class, usually "log"
    • warnLocks

      public static void warnLocks()
      Warn if a thread is holding locks. Used when transitioning to another context.
    • getlastWarnLocksException