[concurrency-interest] Lock Manager

Shaffer, Darron Darron_Shaffer@stercomm.com
Tue, 4 Nov 2003 17:00:46 -0600


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_001_01C3A327.7B20DE5A
Content-Type: text/plain;
	charset="ISO-8859-1"

I have just such a locking tool that I built on top of a ConcurrentHashMap.
I called it a "NamedLockTable".  As Adam notes, it is non-trivial to do this
such that:
 
a) The known key storage doesn't grow without bounds -- released locks are
removed.
b) Locking with an unknown key is cheap.
c) No races occur when a lock is being released and another thread is trying
to acquire the same lock.
 
Another possible feature is to allow locks to time out and be removed
automatically.
 
This same locking model occured as far back as IBM CICS.

-----Original Message-----
From: concurrency-interest-admin@cs.oswego.edu
[mailto:concurrency-interest-admin@cs.oswego.edu]On Behalf Of Adam Messinger
Sent: Tuesday, November 04, 2003 4:36 PM
To: concurrency-interest@altair.cs.oswego.edu
Subject: [concurrency-interest] Lock Manager


Please excuse if this is something which has already been discussed and
found to be out of scope.  I looked back through the archives and couldn't
find a record of it.  I believe that a number of programs have need for
functionality that looks something like this:
 
public interface LockManager {
  public void lock(Object key, Object owner);
  public void tryLock(Object key, Object owner, long time, TimeUnit unit);
 
  public void unlock(Object key, Object owner);
}
 
An example of this in the real world can be found here:
 
http://www.javagroups.com/javagroupsnew/docs/javadoc/org/jgroups/blocks/Lock
Manager.html
<http://www.javagroups.com/javagroupsnew/docs/javadoc/org/jgroups/blocks/Loc
kManager.html> 
 
In addition similar schemes are present in WebLogic Server internals.  In
some places we use a non-blocking variation of this which looks something
like:
 
public interface NonBlockingLockManager extends LockManager {  
  public Future tryLock(Object key, Object owner, long time, TimeUnit unit,
Listener l);

  public Future unlock(Object key, Object owner, Listener l);
 
  public interface Listener {
    // called whenever f.isDone() would start returning true
    public void done(Future f);
  }
}
 
The non-blocking tryLock variation allows us to avoid blocking threads while
trying to gain contended locks.  The non-blocking unlock is needed mostly
for situations where the unlock operation requires I/O.
 
I know that many other applications have need for one or both of these
variations as well.
 
All this is similar, but subtly different, than having a j.u.Map full of
j.u.c.Locks.  One important difference is that the locks may be owned by
something other than a Thread (an example use case is a transaction).
Another difference is that some subtlety is required to remove unused locks
without race conditions which cause simultaneous lock attempts to deadlock.
Finally supporting the Futures is also outside the scope of what the current
Locks can do.
 
What do folks think?  Is it a general enough problem to be included in JSR
166?  Is it too out of place given that it decouples locking from threading?
 
Cheers!

Adam


------_=_NextPart_001_01C3A327.7B20DE5A
Content-Type: text/html;
	charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3DISO-8859-1">


<META content=3D"MSHTML 6.00.2800.1106" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff size=3D2>I have=20
just such a locking tool that I built on top of a =
ConcurrentHashMap.&nbsp; I=20
called it a "NamedLockTable".&nbsp; As Adam notes, it is non-trivial to =
do this=20
such that:</FONT></SPAN></DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff=20
size=3D2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff size=3D2>a)=20
The&nbsp;known key storage&nbsp;doesn't grow without bounds -- released =
locks=20
are removed.</FONT></SPAN></DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff size=3D2>b)=20
Locking with an unknown key is cheap.</FONT></SPAN></DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff size=3D2>c) No=20
races occur when a lock is being released and another thread is trying =
to=20
acquire the same lock.</FONT></SPAN></DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff=20
size=3D2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff=20
size=3D2>Another possible feature is to allow locks to time out and be =
removed=20
automatically.</FONT></SPAN></DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff=20
size=3D2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=3D025485222-04112003><FONT face=3DArial =
color=3D#0000ff size=3D2>This=20
same locking model occured as far back as IBM CICS.</FONT></SPAN></DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
  <DIV class=3DOutlookMessageHeader dir=3Dltr align=3Dleft><FONT =
face=3DTahoma=20
  size=3D2>-----Original Message-----<BR><B>From:</B>=20
  concurrency-interest-admin@cs.oswego.edu=20
  [mailto:concurrency-interest-admin@cs.oswego.edu]<B>On Behalf Of =
</B>Adam=20
  Messinger<BR><B>Sent:</B> Tuesday, November 04, 2003 4:36 =
PM<BR><B>To:</B>=20
  concurrency-interest@altair.cs.oswego.edu<BR><B>Subject:</B>=20
  [concurrency-interest] Lock Manager<BR><BR></FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>Please excuse if this is something =
which has=20
  already been discussed and found to be out of scope.&nbsp; I looked =
back=20
  through the archives and couldn't find a record of it.&nbsp; =
</FONT><FONT=20
  face=3DArial size=3D2>I believe that a number of programs have need =
for=20
  functionality that looks something like this:</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>public interface LockManager =
{</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp; public void lock(Object key, =
Object=20
  owner);</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp; public void tryLock(Object =
key, Object=20
  owner, long time, TimeUnit unit);</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp; public void unlock(Object =
key, Object=20
  owner);</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>}</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>An example of this in the real world =
can be found=20
  here:</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2><A=20
  =
href=3D"http://www.javagroups.com/javagroupsnew/docs/javadoc/org/jgroups=
/blocks/LockManager.html">http://www.javagroups.com/javagroupsnew/docs/j=
avadoc/org/jgroups/blocks/LockManager.html</A></FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>In addition similar schemes are =
present=20
  in&nbsp;WebLogic Server internals.&nbsp; In some places we use a =
non-blocking=20
  variation of this which looks something like:</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV>
  <DIV><FONT face=3DArial size=3D2>public interface =
NonBlockingLockManager extends=20
  LockManager {</FONT><FONT face=3DArial size=3D2>&nbsp; </FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp; public Future tryLock(Object =
key, Object=20
  owner, long time, TimeUnit unit, Listener l);</FONT></DIV>
  <DIV>
  <DIV><FONT face=3DArial size=3D2></FONT></DIV><FONT face=3DArial =
size=3D2>&nbsp;=20
  public Future unlock(Object key, Object owner, Listener =
l);</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp; public interface Listener =
{</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp; // called =
whenever f.isDone()=20
  would start returning true</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp; public void =
done(Future=20
  f);</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>&nbsp; }</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2>}</FONT></DIV></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>The non-blocking tryLock variation =
allows us to=20
  avoid blocking threads while trying to gain contended locks.&nbsp; =
The=20
  non-blocking unlock is needed mostly for situations where the unlock =
operation=20
  requires I/O.</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>I know that many other applications =
have need for=20
  one or both of these variations as well.</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>All this is similar, but subtly =
different, than=20
  having a j.u.Map full of j.u.c.Locks.&nbsp; One important difference =
is that=20
  the locks may be owned by something other than a Thread (an example =
use case=20
  is&nbsp;a transaction).&nbsp; Another difference is that some =
subtlety is=20
  required to remove unused locks without race conditions which cause=20
  simultaneous lock attempts to deadlock.&nbsp; Finally supporting the =
Futures=20
  is also outside the scope of what the current Locks can =
do.</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial size=3D2>What do folks think?&nbsp; Is it a =
general enough=20
  problem to be included in JSR 166?&nbsp; Is it too out of place given =
that it=20
  decouples locking from threading?</FONT></DIV>
  <DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3DArial=20
size=3D2>Cheers!<BR><BR>Adam</FONT></DIV></BLOCKQUOTE></BODY></HTML>

------_=_NextPart_001_01C3A327.7B20DE5A--