public class NonBlockingLockManager<R extends Comparable<R>> extends Object
ResourceQueue
is created for each resource and used to block
operations that are awaiting a lock. When locks are not being pre-declared, a
WAITS_FOR
graph is additionally used to detect deadlocks.
This implementation uses a single AcceptTask
thread to accept tasks,
update the requests in the ResourceQueue
s, and in general perform
housekeeping for the internal state. Tasks submitted to this class ARE NOT
bound to a worker thread until they are executed by the delegate
Executor
.
Modifier and Type | Class and Description |
---|---|
protected static class |
NonBlockingLockManager.Counters
Counters for the
NonBlockingLockManager . |
protected class |
NonBlockingLockManager.LockFutureTask<T>
FutureTask which executes once it holds its locks. |
protected class |
NonBlockingLockManager.ResourceQueue<T extends NonBlockingLockManager.LockFutureTask<? extends Object>>
Unbounded queue of operations waiting to gain an exclusive lock on a
resource.
|
static class |
NonBlockingLockManager.RunState
Run states for the
NonBlockingLockManager . |
Modifier and Type | Field and Description |
---|---|
protected static boolean |
DEBUG |
protected Executor |
delegate
Tasks holding their locks are submitted to this service for execution.
|
protected static boolean |
INFO |
protected static org.apache.log4j.Logger |
log |
protected TxDag |
waitsFor
Used to track dependencies among transactions.
|
Constructor and Description |
---|
NonBlockingLockManager(int maxConcurrency,
boolean predeclareLocks,
Executor delegate)
Create a lock manager.
|
Modifier and Type | Method and Description |
---|---|
CounterSet |
getCounters() |
boolean |
isOpen() |
boolean |
isShutdown() |
boolean |
isTerminated() |
void |
releaseLocksForTask(R[] resource)
Release all locks held by the
NonBlockingLockManager.LockFutureTask currently holding a
lock on the specified resource. |
void |
shutdown() |
void |
shutdownNow() |
<T> Future<T> |
submit(R[] resource,
Callable<T> task)
Submit a task for execution.
|
<T> Future<T> |
submit(R[] resource,
Callable<T> task,
TimeUnit unit,
long lockTimeout,
int maxLockTries) |
String |
toString() |
protected static final org.apache.log4j.Logger log
protected static final boolean INFO
protected static final boolean DEBUG
protected final TxDag waitsFor
protected final Executor delegate
public NonBlockingLockManager(int maxConcurrency, boolean predeclareLocks, Executor delegate)
true
as deadlocks are
impossible and we do not maintain a WAITS_FOR graph.maxConcurrency
- The maximum multi-programming level (ignored if
predeclareLocks is true
).predeclareLocks
- When true
, operations MUST declare all locks
before they begin to execute. This makes possible several
efficiencies and by sorting the resources in each lock request
into a common order we are able to avoid deadlocks entirely.delegate
- The service on which the tasks will be executed.
Note: The delegate MUST NOT use a bounded queue or
cause tasks to be run in the caller's thread. The use of a
SynchronousQueue
or an unbounded
LinkedBlockingQueue
for the delegate's
workQueue are both acceptable.
Note: If Executor.execute(Runnable)
blocks for the
delegate then the AcceptTask
will also block
and this class will be non-responsive until the delegate
has accepted each [waitingTask] for execution. Some
Executor
s can cause the task to be run in the
caller's thread, which would be the AcceptTask
itself
and which also has the effect of causing this class to be
non-responsive until the task is complete.
public final void releaseLocksForTask(R[] resource)
NonBlockingLockManager.LockFutureTask
currently holding a
lock on the specified resource.resource[]
- The declared locks for the task.
FIXME This is an integration hack for AbstractTask
.
AbstractTask
needs to be able to release the locks as soon as the
work of an unisolated task is done (when it is waiting for a group
commit) so that other tasks can gain access to the same indices and make
it into the same group commit. It is using this method to obtain the
NonBlockingLockManager.LockFutureTask
and then release its locks.
AbstractTask
really needs a refactor.
public CounterSet getCounters()
public <T> Future<T> submit(R[] resource, Callable<T> task)
FutureTask.get()
to await the outcome.resource
- An array of resources whose locks are required to execute the
task.task
- The task to be executed.IllegalArgumentException
- if resource is null
or if any element
of that array is null
.IllegalArgumentException
- if the task is null
.RejectedExecutionException
- if the task can not be queued for execution (including if the
service is not running or if a blocking queue was used and
the queue is at capacity).public <T> Future<T> submit(R[] resource, Callable<T> task, TimeUnit unit, long lockTimeout, int maxLockTries)
public boolean isOpen()
public boolean isShutdown()
public boolean isTerminated()
public void shutdown()
public void shutdownNow()
Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.