|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectbb.util.ThreadMonitor
public class ThreadMonitor
Class which actively monitors the thread state of a JVM looking for issues.
Reports events as they are detected to any registered ThreadMonitorListener
s.
Monitoring is started by calling startMonitoring
,
is stopped by calling stopMonitoring
,
and isMonitoring
reports if monitoring is currently active.
It is legitimate to start and stop monitoring as often as desired.
There are certain situations where the code has to record information
but no reference to an appropriate external handler class is available.
A prime example is if during the monitoring or listener callback a Throwable is caught.
Rather than write the information to a console that could disappear when the application quits,
each instance of this class instead maintains a logger2
field where this information is written to.
The current implementation logs to a file in the standard log directory
.
This class is multithread safe: almost every method (including private ones) is synchronized. The sole exceptions are the private fireXXX methods. These methods are called internally by this class and interact with arbitrary external ThreadMonitorListener classes. As a strategy to prevent deadlock, it is critical that the thread which calls these fireXXX methods initially owns no locks. Thus, these methods must be unsynchronized, since otherwise the lock on this ThreadMonitor instance would be held.
Nested Class Summary | |
---|---|
private class |
ThreadMonitor.MonitorTask
Class which detects thread issues and calls the appropriate fireXXX event notification method. |
static class |
ThreadMonitor.UnitTest
See the Overview page of the project's javadocs for a general description of this unit test class. |
Field Summary | |
---|---|
private boolean |
deadlocked
Records whether or not thread deadlock has been detected. |
private long |
instanceId
This instance's Id. |
private static AtomicLong |
instanceIdNext
The next ThreadMonitor instance's instanceId field. |
private long |
interval
Specifies how often the thread state should be checked. |
private static long |
interval_default
Default value for interval . |
private Set<ThreadMonitorListener> |
listeners
Set of all ThreadMonitorListener s that are interested in thread events. |
private Logger2 |
logger2
Logger where certain information (e.g. otherwise unhandleable errors) gets written to. |
private ThreadMonitor.MonitorTask |
monitorTask
ThreadMonitor.MonitorTask used to measure the thread state. |
private int |
nextLoggerId
The next logger2 's Id. |
private int |
nextTimerId
The next timer value's Id. |
private String |
state
Last thread state that was detected. |
private Timer |
timer
|
Constructor Summary | |
---|---|
ThreadMonitor()
Simply calls . |
|
ThreadMonitor(ThreadMeasurer measurer,
long interval)
Constructor. |
Method Summary | |
---|---|
boolean |
addListener(ThreadMonitorListener listener)
Attempts to add listener to an internal set. |
private void |
fireOnDeadlocked(String state)
|
private void |
fireOnMonitoringError(Throwable t)
|
private void |
fireOnMonitoringStarted()
|
private void |
fireOnMonitoringStopped()
|
private void |
fireOnNotDeadlocked(String state)
|
private void |
fireOnThreadState(String state)
|
private void |
flushLoggerIfCreated()
Flushes logger2 if and only if it has been created. |
private boolean |
getDeadlocked()
|
private ThreadMonitorListener[] |
getListeners()
Returns a defensive copy of listeners for use by the fireXXX methods. |
private Logger2 |
getLogger2()
Returns logger2 , lazy initializing it if necessary. |
private String |
getLoggerSuffix()
Returns a suffix to assign to logger2 's filename whenever it is assigned. |
String |
getThreadState()
Returns the thread state that was detected at the last check cycle. |
private String |
getTimerName()
Returns a name to assign to timer whenever it is assigned. |
boolean |
isDeadlocked()
Reports whether or not thread deadlock was detected at the last check cycle. |
boolean |
isMonitoring()
Reports whether or not this instance is actively monitoring threads. |
boolean |
removeListener(ThreadMonitorListener listener)
Attempts to remove listener from an internal set. |
private void |
setDeadlocked(boolean deadlocked)
|
private void |
setThreadState(String state)
|
boolean |
startMonitoring()
Starts monitoring if it is currently not happening. |
boolean |
stopMonitoring()
Stops monitoring if it is currently happening. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private static final long interval_default
interval
.
The current value for this constant is 10 seconds.
See benchmark_impactOfMonitoring
for why it was determined that this value should not burden a JVM excessively.
private static final AtomicLong instanceIdNext
instanceId
field.
Contract: is initialized to 0, and if this field has that value, it means that no instances have been created.
private final long instanceId
private int nextTimerId
timer
value's Id.
Contract: is initialized to 1, and if this field has that value, it means that timer has never been assigned.
private Timer timer
private final ThreadMonitor.MonitorTask monitorTask
ThreadMonitor.MonitorTask
used to measure the thread state.
Contract: is never null.
private final long interval
Units: milliseconds.
Contract: is > 0.
private String state
private boolean deadlocked
private final Set<ThreadMonitorListener> listeners
ThreadMonitorListener
s that are interested in thread events.
Contract: is never null nor contains null elements.
private int nextLoggerId
logger2
's Id.
Contract: is initialized to 1, and if this field has that value, it means that logger2 has never been assigned.
private Logger2 logger2
Note: this field is lazy initialized inside getLogger2
(because this field will never be used in well behaved applications),
may be flushed in flushLoggerIfCreated
(if previously initialized),
and is closed and nulled out in stopMonitoring
(if previously initialized).
All other code should always use getLogger2 and never directly access this field.
Constructor Detail |
---|
public ThreadMonitor()
this
(new ThreadMeasurer.ThreadMeasurer()
, interval_default
)
.
public ThreadMonitor(ThreadMeasurer measurer, long interval) throws IllegalArgumentException
IllegalArgumentException
- if measurer == null; interval <= 0Method Detail |
---|
public boolean startMonitoring()
Timer
that executes monitorTask
at a rate specified by interval
.
This method may safely be called multiple times (if the first call succeeds, subsequent calls do nothing).
private String getTimerName()
timer
whenever it is assigned.
Attempts to return a value that is both unique to this instance
as well as unique to each of this instance's timer values.
public boolean isMonitoring()
public boolean stopMonitoring()
This method may safely be called multiple times (if the first call succeeds, subsequent calls do nothing).
public String getThreadState() throws IllegalStateException
This method never causes a new thread state measurement to be made,
so it executes extremely quickly, and may be called frequently with low impact on the JVM.
On the other hand, the result may be obsolete,
especially if this instance was constructed with a large value for interval
.
IllegalStateException
- if instance is currently not monitoring (i.e. isMonitoring
returns false)private void setThreadState(String state)
public boolean isDeadlocked() throws IllegalStateException
This method never causes a new thread state measurement to be made,
so it executes extremely quickly, and may be called frequently with low impact on the JVM.
On the other hand, the result may be obsolete,
especially if this instance was constructed with a large value for interval
.
IllegalStateException
- if instance is currently not monitoring (i.e. isMonitoring
returns false)private boolean getDeadlocked()
private void setDeadlocked(boolean deadlocked)
private ThreadMonitorListener[] getListeners()
listeners
for use by the fireXXX methods.
This is important both for multithread safety (see this class's javadocs)
and for reasons explained in this forum posting.
public boolean addListener(ThreadMonitorListener listener) throws IllegalArgumentException
IllegalArgumentException
- if listener == nullpublic boolean removeListener(ThreadMonitorListener listener) throws IllegalArgumentException
IllegalArgumentException
- if listener == nullprivate void fireOnMonitoringStarted()
private void fireOnMonitoringStopped()
private void fireOnMonitoringError(Throwable t)
private void fireOnThreadState(String state)
private void fireOnDeadlocked(String state)
private void fireOnNotDeadlocked(String state)
private Logger2 getLogger2()
logger2
, lazy initializing it if necessary.
private String getLoggerSuffix()
logger2
's filename whenever it is assigned.
Attempts to return a value that is both unique to this instance
as well as unique to each of this instance's logger2 values.
private void flushLoggerIfCreated()
logger2
if and only if it has been created.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |