public class ThreadSignalHandler extends AbstractSignalHandler
Thread
class
to communicate signals back to the SignalTarget
. This handler only
supports the Signal.ABORT
signal. When this signal is received,
Thread.interrupt()
is called on the thread that was registered with
this handler. This should typically be a worker thread for some process.
The worker thread should regularly check Thread.interrupted()
to see if it has been interrupted. If the thread may be waiting for a blocking
call to end, it should be able to handle the resulting InterruptedException
that is thrown if the thread is interrupted.
If the worker thread becomes interrupted it should stop what it is doing, cleanup any allocated resources and exit in a timely fasion. Here is a general outline:
// ... code in worker thread threadSignalHandler.setWorkerThread(null); beginTransaction(); boolean done = false; boolean interrupted = false; while (!done && !interrupted) { try { done = doSomeWork(); // NOTE! This must not take forever! interrupted = Thread.interrupted(); } catch (InterruptedException ex) { // NOTE! Try-catch is only needed if thread calls a blocking method interrupted = true; } } if (interrupted) { rollbackTransaction(); } else { commitTransaction(); }
Modifier and Type | Field and Description |
---|---|
private boolean |
forceStop
If TRUE, call Thread.stop() instead of Thread.interrupt()
|
private boolean |
hasAborted
If TRUE, at least one ABORT signal has been recieved.
|
private static ThreadLocal<InterruptHandler> |
interruptHandler
Keep per-thread interupt handlers.
|
private static org.slf4j.Logger |
logger
Log signals processing.
|
private static Set<Signal> |
supported |
private Thread |
workerThread
The worker thread that should be interrupted when
Signal.ABORT is
received. |
Constructor and Description |
---|
ThreadSignalHandler()
Create a new thread signal handler.
|
ThreadSignalHandler(Thread workerThread)
Create a new thread signal handler.
|
Modifier and Type | Method and Description |
---|---|
static void |
checkInterrupted()
Utility method to check if the current thread has been interrupted
and (may) throw a SignalException if it has.
|
void |
handleSignal(Signal signal)
Only handles the
Signal.ABORT signal. |
boolean |
hasReceived(Signal signal)
Check if the given signal has been received by this signal handler.
|
void |
setForceStop(boolean forceStop)
Call this method with a true value to make the signal handler
use
Thread.stop(Throwable) instead of Thread.interrupt() . |
static void |
setInterruptHandler(InterruptHandler handler)
Register an interrupt handler with the current thread.
|
void |
setWorkerThread(Thread workerThread)
Set the worker thread that should be interrupted when a signal is
receiver.
|
addSignal, getSupportedSignals, removeSignal, supports
private static ThreadLocal<InterruptHandler> interruptHandler
ExceptionInterruptHandler
which simply throws a
SignalException
if the current thread has been
interrupted.private static final org.slf4j.Logger logger
private Thread workerThread
Signal.ABORT
is
received.private boolean forceStop
private boolean hasAborted
public ThreadSignalHandler()
Signal.ABORT
signal.public ThreadSignalHandler(Thread workerThread)
workerThread
- The worker thread to interrupt when it receieves the
Signal.ABORT
signal, or null to interrupt the current threadpublic static void checkInterrupted()
InterruptHandler
that has been registered
for the current thread by setInterruptHandler(InterruptHandler)
.
The default handler always throws a SignalException
.public static void setInterruptHandler(InterruptHandler handler)
checkInterrupted()
method when the thread
has been interrupted. If no handler has been registered with a
thread the default action is to throw a SignalException
.handler
- An interrupt handler or null to remove a previously
registered handlerpublic void handleSignal(Signal signal)
Signal.ABORT
signal. When receieved,
Thread.interrupt()
is called on the worker thread that was
registered when this object was created. Note that this method
called from a different thread. The worker thread is busy doing something
else. If the worker thread has already ended, this method does nothing.signal
- The signal, only Signal.ABORT
is acceptedUnsupportedSignalException
- If signal is anything else than
Signal.ABORT
public void setWorkerThread(Thread workerThread)
workerThread
- The worker thread, or null to use the current threadpublic void setForceStop(boolean forceStop)
Thread.stop(Throwable)
instead of Thread.interrupt()
.
Note that the Thread.stop
method is deprecated and it is not
recommended that it is used. For some plug-ins though this may be the
only option, if they are mainly executing code outside of their control
which doesn't check the Thread.interrupted()
status. The exception
passed to the thread will be a InterruptedException
.forceStop
- TRUE to stop the thread by force, FALSE to signal to
it with a flagpublic boolean hasReceived(Signal signal)
signal
- The signal to check for