Class ThreadingUtil
- java.lang.Object
-
- jmri.util.ThreadingUtil
-
@ThreadSafe public class ThreadingUtil extends java.lang.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.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
ThreadingUtil.ReturningThreadAction<E>
Interface for use in ThreadingUtil's lambda interfacesstatic interface
ThreadingUtil.ThreadAction
Interface for use in ThreadingUtil's lambda interfacesstatic interface
ThreadingUtil.ThreadActionWithJmriException
Interface for use in ThreadingUtil's lambda interfaces
-
Constructor Summary
Constructors Constructor Description ThreadingUtil()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static boolean
canThreadRun(java.lang.Thread t)
Check whether a specific thread is running (or able to run) right now.static java.lang.ThreadGroup
getJmriThreadGroup()
Get the JMRI default thread group.java.lang.RuntimeException
getlastWarnLocksException()
static boolean
isGUIThread()
Check if on the GUI event dispatch thread.static boolean
isLayoutThread()
Check if on the layout-operation thread.static boolean
isThreadWaiting(java.lang.Thread t)
Check whether a specific thread is currently waiting.static java.lang.Thread
newThread(java.lang.Runnable runner)
Create a new thread in the JMRI groupstatic java.lang.Thread
newThread(java.lang.Runnable runner, java.lang.String name)
Create a new thread in the JMRI group.static void
requireGuiThread(org.slf4j.Logger logger)
Check that a call is on the GUI thread.static void
requireLayoutThread(org.slf4j.Logger logger)
Check that a call is on the Layout thread.static void
runOnGUI(ThreadingUtil.ThreadAction ta)
Run some GUI-specific code before returningstatic javax.swing.Timer
runOnGUIDelayed(ThreadingUtil.ThreadAction ta, int delay)
Run some GUI-specific code at some later point, at least a known time in the future.static void
runOnGUIEventually(ThreadingUtil.ThreadAction ta)
Run some GUI-specific code at some later point.static void
runOnGUIWithJmriException(ThreadingUtil.ThreadActionWithJmriException ta)
Run some GUI-specific code before returning.static <E> E
runOnGUIwithReturn(ThreadingUtil.ReturningThreadAction<E> ta)
Run some GUI-specific code before returning a value.static void
runOnLayout(ThreadingUtil.ThreadAction ta)
Run some layout-specific code before returning.static javax.swing.Timer
runOnLayoutDelayed(ThreadingUtil.ThreadAction ta, int delay)
Run some layout-specific code at some later point, at least a known time in the future.static void
runOnLayoutEventually(ThreadingUtil.ThreadAction ta)
Run some layout-specific code at some later point.static void
runOnLayoutWithJmriException(ThreadingUtil.ThreadActionWithJmriException ta)
Run some layout-specific code before returning.static void
warnLocks()
Warn if a thread is holding locks.
-
-
-
Constructor Detail
-
ThreadingUtil
public ThreadingUtil()
-
-
Method Detail
-
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
-
runOnLayoutWithJmriException
public static void runOnLayoutWithJmriException(@Nonnull ThreadingUtil.ThreadActionWithJmriException ta) throws JmriException, java.lang.RuntimeException
Run some layout-specific code before returning. This method catches and rethrows JmriException and RuntimeException.Typical uses:
ThreadingUtil.runOnLayout(() -> { sensor.setState(value); });
- Parameters:
ta
- What to run, usually as a lambda expression- Throws:
JmriException
- when an exception occursjava.lang.RuntimeException
- when an exception occurs
-
runOnLayoutEventually
public static void runOnLayoutEventually(@Nonnull ThreadingUtil.ThreadAction ta)
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
@Nonnull public static javax.swing.Timer runOnLayoutDelayed(@Nonnull ThreadingUtil.ThreadAction ta, int delay)
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 expressiondelay
- 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 returningTypical 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
-
runOnGUIWithJmriException
public static void runOnGUIWithJmriException(@Nonnull ThreadingUtil.ThreadActionWithJmriException ta) throws JmriException, java.lang.RuntimeException
Run some GUI-specific code before returning. This method catches and rethrows JmriException and RuntimeException.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- Throws:
JmriException
- when an exception occursjava.lang.RuntimeException
- when an exception occurs
-
runOnGUIwithReturn
public static <E> E runOnGUIwithReturn(@Nonnull ThreadingUtil.ReturningThreadAction<E> ta)
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
public static void runOnGUIEventually(@Nonnull ThreadingUtil.ThreadAction ta)
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
@Nonnull public static javax.swing.Timer runOnGUIDelayed(@Nonnull ThreadingUtil.ThreadAction ta, int delay)
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 expressiondelay
- 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 java.lang.Thread newThread(java.lang.Runnable runner)
Create a new thread in the JMRI group- Parameters:
runner
- Runnable.- Returns:
- new Thread.
-
newThread
public static java.lang.Thread newThread(java.lang.Runnable runner, java.lang.String name)
Create a new thread in the JMRI group.- Parameters:
runner
- Thread runnable.name
- Thread name.- Returns:
- New Thread.
-
getJmriThreadGroup
public static java.lang.ThreadGroup getJmriThreadGroup()
Get the JMRI default thread group. This should be passed to as the first argument to theThread
constructor so we can track JMRI-created threads.- Returns:
- JMRI default thread group.
-
canThreadRun
public static boolean canThreadRun(@Nonnull java.lang.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 java.lang.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)
andisThreadWaiting(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
public java.lang.RuntimeException getlastWarnLocksException()
-
-