This class allows mutual exclusive access to resources shared by different threads. In other words, access to certain data that is accessed by different threads, can be protected if each thread (aka critical section code) uses the same ThreadLock to control the access to such data.
If an acquire() is not followed by a corresponding release(), other threads will not be able to gain control to this object and will wait endlessly (deadlock situation). To avoid this, it is a good practice to embed pairs of acquire()/release() calls into try/finally statements as follows:
try { tl.acquire(); ...critical section code .... } finally { tl.release() }
ThreadLock uses an internal counter to allow multiple calls to acquire() and to be freed only when a same amount of release() calls are performed. This behavior can be switched off by a constructor parameter. If switched off, each recursive acquire() call will not be counted and each call to release() will instantly free the mutex. This mode is not very recommended, the standard use is recursive mode.
Furthermore, ThreadLock allows to disable locking using setUnsafe(). The objective here is to gain execution speed, as thread synchronization causes relatively expensive system calls. Nevertheless, it is sometimes obvious that the same code may run in a thread safe mode one time and without thread locking the next time. Therefore, for performance critical code, it is quite useful to be able to control this behavior.
Caution: Use this class with great care. Deadlocks are not easy to detect and debug. Use this class only if standard synchronization of the Java language seems too limited and mechanisms like the class uses internally would need to be implemented.
Public Fields | |
int | recursionWarningThreshold = 10 |
int | waitWarningTimeLimitInMillis = 1000 |
Public Methods | |
ThreadLock () | |
ThreadLock (LockMode lockMode) | |
ThreadLock (LockMode lockMode, Safeness safeness) | |
void | acquire () |
int | dbgCountAcquirements (Thread thread) |
LockMode | getMode () |
Safeness | getSafeness () |
void | release () |
void | setSafeness (Safeness safeness) |
String | toString () |
boolean | willRelease () |
Protected Fields | |
int | cntAcquirements |
boolean | createOwnerStackTrace = false |
LockMode | lockMode |
Object | mutex |
Thread | owner |
Exception | ownerException |
Ticks | waitTime = new Ticks() |
Package Access Methods | |
void | constructor (LockMode lockMode, Safeness safeness) |
ThreadLock | ( | ) |
Create a ThreadLock that allows recursion.
ThreadLock | ( | LockMode | lockMode | ) |
Create a ThreadLock that allows recursion. A warning will be given (ALIB Error) when the given recursion level is reached (and each multiple of it).
lockMode | (Optional) Flag if recursion support is on (the default). If not, nested locks are not counted. |
ThreadLock | ( | LockMode | lockMode, |
Safeness | safeness | ||
) |
Create a ThreadLock that allows recursion. A warning will be given (ALIB Error) when the given recursion level is reached (and each multiple of it). In addition the lock can be initialized to be unsafe, which means the locking critical sections is disabled.
lockMode | (Optional) Flag if recursion support is on (the default). If not, nested locks are not counted. |
safeness | (Optional) Defaults to Safeness.Safe . See setSafeness for more information. |
void acquire | ( | ) |
Thread which invokes this method gets registered as the current owner of this object, until the same thread releases the ownership invoking release(). In the case that this object is already owned by another thread, the invoking thread is suspended until ownership can be gained. Multiple (nested) calls to this method are counted and the object is only released when the same number of release() calls have been made.
Reimplemented in Lox.
Used by the Constructors to create an instance.
lockMode | (Optional) Flag if recursion support is on (the default). If not, nested locks are not counted. |
safeness | See setSafeness for more information. |
int dbgCountAcquirements | ( | Thread | thread | ) |
Returns the number of acquirements of this ThreadLock. The negative number (still providing the number of acquirements) is returned if the owning thread is not the same as the given one.
thread | The thread to test current ownership of this. Defaults to the current (invoking) thread. |
LockMode getMode | ( | ) |
Query if this instance was set to work recursively.
Safeness getSafeness | ( | ) |
Query if this instance was set to unsafe mode.
void release | ( | ) |
void setSafeness | ( | Safeness | safeness | ) |
If parameter is true, the whole locking system is disabled. The only objective here is to to gain execution speed, as thread synchronization causes relatively expensive system calls. Use this method only if you are 100% sure that your (otherwise) critical section are executed in a single threaded environment. And: "relative expensive" means: they are not really expensive. This is provided only for the rare case that your critical section is very, very frequently executed.
safeness | Determines if this object should use a mutex (Safeness.Safe ) or just do nothing (Safeness.Unsafe ). |
String toString | ( | ) |
This is for debugging purposes. E.g. this enables the Eclipse IDE to display object descriptions in the debugger.
Reimplemented in Logger.
boolean willRelease | ( | ) |
Returns true
if the next invocation of release will release the lock. Returns false
, if recursive acquirements have been performed.
true
if locked exactly once.
|
protected |
Counter for the number of acquire() calls of the current thread.
|
protected |
If set to true, whenever acquired, the stack trace of the acquirement is stored. Can be set to true
for debugging deadlocks. Stack trace will be reported when waitWarningTimeLimitInMillis is exceeded.
|
protected |
Flag if recursion support is on. If not, nested locks are not counted.
|
protected |
The internal object to lock on.
|
protected |
The current owner of the ThreadLock.
|
protected |
Used for dumping stack trace of location of owner. For performance reasons, created only if public field createOwnerStackTrace was set to true
.
int recursionWarningThreshold = 10 |
Limit of recursions. If limit is reached or a multiple of it, an error message is passed to ReportWriter. Defaults is 10.
int waitWarningTimeLimitInMillis = 1000 |
This is a threshold that causes acquire() to send a warning to ReportWriter if acquiring the access takes longer than the given number of milliseconds. To disable such messages, set this value to 0. Default is 1 second.