|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectcom.ibm.datapower.wamt.clientAPI.Lock
public class Lock
An implementation of a re-entrant lock that can be either blocking (like
synchronized
) or non-blocking (fail-fast). The purpose of this
implementation is to provide a lock to write methods with the ability to test
if another thread already owns the lock. That is not available with the
synchronized
keyword.
All updates (writes) to anything in an object that uses Lock
must
invoke lockNoWait()
, whether done by the clientAPI or
internally via a background thread. Each object that uses Lock
has
its own instance of a Lock
object, these instances of
Lock
operate independently of each other (e.g., calling lockNoWait()
on one device does not prevent using (locking) another device on another thread.
The intention is for callers of the clientAPI to invoke only short-running
tasks. If the lock exists when the clientAPI is invoked (for example, because
a separate thread already has it locked for a short running or long running
task), the clientAPI method which does not own the lock will fail with an
LockBusyException
.
Anything long-running should be queued for execution by a background thread
(see ProgressContainer
). If the background execution queue is already
full (which is not the default behavior), then a FullException will be
thrown. (For more information about this circumstance, see
FullException
.) Instead of failing fast, the background execution
thread should block until the lock is available, since there is no user
interface penalty when a background thread blocks for a long period.
Locking design:
The following may seem unnecessarily complicated (i.e., why not just use
synchronized
?), but there are some unusual requirements:
The public clientAPI methods must not be long-running. If there is a task that requires a long run, then it should be queued for another thread to execute. This is because the UI (consumer of the clientAPI) must be responsive and not block for indeterminate periods. The UI could be any client (i.e., servlet, or a rich client).
Locks are fail-fast. If a thread tries to acquire a lock that is already held
by another thread, the thread trying to acquire the busy lock will fail
without blocking or waiting. This means that callers should expect to either
acquire the lock quickly, or receive an exception quickly. If a caller
receives an exception while trying to acquire a lock, it may (at the caller's
discretion) retry the lock acquisition at a later time or abort the entire
operation. [Note: requests for locks via the clientAPI should fail-fast.
However, daemons can wait for locks to be acquired, so this class provides a
lockWait()
method that will block until the lock is available.
So this class needs to support both fail-fast acquisition and blocking
acquisition.]
If the thread is unable to obtain all the locks it requires, it should fail and release the locks it was able to obtain up until the failure point.
Objects that implement the Persistable
interface can be
persisted to a datastore using the dataAPI. Those objects can be deleted from
the datastore. If you try to use an object that has been deleted from the
datastore and you still have a reference to that object, it will throw a
DeletedException. This is necessary because the datastore has the notion of a
delete or destructor, but Java objects do not have the notion of a destructor
that can be immediately invoked such as in C++. It is not considered
acceptable to access a persistable Java object that was deleted from the
datastore. If this occurs, an exception will be thrown. Because the clientAPI
has a lot of persistence, a lot of the clientAPI methods will throw a
DeletedException.
All the Lock methods are synchronized
, meaning that access is
serialized around the lock, not serializing around the work areas directly.
Field Summary | |
---|---|
static java.lang.String |
COPYRIGHT_2009_2013
|
Constructor Summary | |
---|---|
Lock(java.lang.String name)
Create a mutex lock. |
Method Summary | |
---|---|
boolean |
isAvailable()
Check if the lock is available for acquisition by this thread. |
void |
lockNoWait()
Try to acquire the lock, but fail fast if the lock is held by another thread. |
void |
lockWait()
Acquire the lock, even if it requires blocking until another thread releases this lock. |
java.lang.String |
toString()
Get a String representation of this object for the purpose of debugging or tracing. |
void |
unlock()
Release the current lock, or decrement the reentrancy counter. |
Methods inherited from class java.lang.Object |
---|
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
public static final java.lang.String COPYRIGHT_2009_2013
Constructor Detail |
---|
public Lock(java.lang.String name)
lockWait()
,
lockNoWait()
) to trigger the lock to prevent other threads from
acquiring it.
name
- a human-readable name for the lock. This name will appear in
log and exception messages and in the method toString()
.Method Detail |
---|
public boolean isAvailable()
public void lockWait()
public void lockNoWait() throws LockBusyException
LockBusyException
immediately. This method does not block,
so it should return (successfully or with an exception) quickly. Usually
most clientAPI invocations from a user interface will use this method,
since the user interface is sensitive to long-running methods on its
threads.
public void unlock()
public java.lang.String toString()
toString
in class java.lang.Object
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |