[concurrency-interest] "Lock" API and built-in locks

Doug Lea dl@cs.oswego.edu
Wed, 25 Jun 2003 08:43:22 -0400


Dear concurrency-interest list members,

As we head toward stabilizing specs and implementations, we (the
JSR-166 expert group) would like your opinions on another API issue.

JSR-166 provides a highly flexible framework for "fancy" locks --
supporting trylock, interruptibility, timeouts, multiple conditions
per lock, etc., using the Lock and Condition interfaces along with
concrete ReentrantLock and FairReentrantLock implementations. Plus
support for rolling your own special-purpose versions.

JSR-166 also currently includes support for a subset of these new
features on built-in monitors via the "Locks" class. The intent was to
provide relief for some of the most frequently complained about
problems with built-in monitors that could be accommodated without
changing the fundamental properties of "synchronized", wait, notify,
notifyAll: This basically amounts to Locks.attempt -- a way of
obtaining trylocks (passing in Runnables), and provision of a
Condition implementation that allows multiple Conditions per built-in
lock.

The question at hand is whether this subset is worth providing.
Here are some of the considerations making me think that it is NOT.

1. Adding ANY kind of extensions for built-in locks adds to
   their apparent complexity for novice and casual users.

2. j.u.c provides the approx ten most common kinds classes that people
   historically used clever locking and monitors for.  So, we hope,
   fewer and fewer application-level programmers will be using monitor
   methods anyway. Why bother making them only a little bit nicer to
   use now?

3. Conversely, any (systems/library level) developer creating a class
   that supports JSR-166's standard set of wait/try/timeout control
   policies for possibly-blocking methods (that are used consistently
   in all of our APIs) will almsot surely need to use a "fancy"
   version of a Lock (almost always ReentrantLock) to implement it
   anyway, so will not use extensions of built-ins.

4. Locks.attempt is a very heavy sledgehammer for obtaining trylock on
   builtins. It is suitable only for emergency maneuvers to wriggle out
   of tight corners that would be better avoided using Lock objects in
   the first place.

5. If we dropped support for built-in lock extensions, then it would make
   more sense to create a subpackage java.util.concurrent.locks (containing
   Lock, Condition, ReadWriteLock) that would better convey that these
   classes are at a lower level and designed for more advanced usage than
   the "everyday usage" APIs like Executor and BlockingQueue. (This is
   the reasoning behind the similar segregation of atomics.)

Does anyone have a compelling argument for keeping built-in lock
extensions?

Thanks very much for the help!!

-Doug

PS JSR-166 preliminary release #2, containing a bunch of clean-ups and
   bug-fixes, plus an emulation mode allowing (slow) use of most
   features on unadulterated JVMs, will be out within a day or
   so. I'll send out mail announcing.