[concurrency-interest] Announcing backport of JSR166 to Java 1.4
Dawid Kurzyniec
dawidk@mathcs.emory.edu
Fri, 17 Sep 2004 01:40:11 -0500
Hello everybody,
I am happy to announce availability of a backport of
java.util.concurrent API to Java 1.4. The backport is based on sources
from JSR 166 CVS repository (September 2004), and dl.util.concurrent
1.3.4. The backport is nearly complete; unsupported functionality is
limited mostly to the following classes: 1) requiring explicit JVM
support (e.g. nanosecond clock), 2) some non-essential functions
described as "designed primarily for use in monitoring in system state,
not for synchronization control", 3) functionality that would affect
performance, or 4) functionality that would require development of
substantial amount of new code.
The backport will probably go into the Emory Utilities package
(http://www.mathcs.emory.edu/dcl/util/). However, the interest expressed
earlier in this list motivates releasing the library as soon as
possible. Hence I am hereby releasing the "still warm" version. The
purpose of this library is to enable gradual transition from Java 1.4 to
5.0: the library allows to develop concurrent applications for Java 1.4
that will work with Java 5.0 by simply changing package names.
So here it is:
http://www.mathcs.emory.edu/dcl/util/util-concurrent.jar (binaries)
http://www.mathcs.emory.edu/dcl/util/util-concurrent-src.jar (source code)
http://www.mathcs.emory.edu/dcl/util/util-concurrent-doc.jar (javadoc)
This is NOT an emulation: it is adaptation of JSR 166 and dl.u.c. code
to Java 1.4. Performance levels of this backport are comparable to dl.u.c.
Overview of supported functionality:
all JSR 166 executors, utilities, and everything related (thread pools,
FutureTask, scheduled tasks and executors, etc)
Locks: ReentrantLock, Semaphore, ReentrantReadWriteLock (see remarks
below), Conditions
Queues: synchronous, array, linked, delay, and priority queues
Atomics: everything except reflection-based updaters
Other concurrency utils: CountDownLatch, CyclicBarrier
Collections: ConcurrentHashMap, CopyOnWriteArrayList, CopyOnWriteArraySet
As far as stability and reliability is considered: the library passes
all of attempted 941 tests from tck test package designed for
java.util.concurrent (the tests of unsupported funcionality were
skipped). Occasionally, there are failures of "condition timeout" test
cases of boolean Condition.await(timeout) and boolean
Condition.awaitUntil(Date), but it is because the tests assume stronger
semantics than required by the specification (see comments on Condition
below).
The following classes were unit-tested:
AbstractExecutorService
AbstractQueue
ArrayBlockingQueue
AtomicBoolean
Atomic[Integer,Long]Array
Atomic[Integer,Long]
AtomicMarkableReference
AtomicReferenceArray
AtomicReference
AtomicStampedReference
ConcurrentHashMap
CopyOnWriteArray[List,Set]
CountDownLatch
CyclicBarrier
DelayQueue
Exchanger
Executors
ExecutorCompletionService
FutureTask
LinkedBlockingQueue
PriorityBlockingQueue
PriorityQueue
ReentrantLock
ReentrantReadWriteLock
ScheduledExecutor
Semaphore
SynchronousQueue
ThreadLocal
ThreadPoolExecutor
TimeUnit
It is also important to stress out that vast proportion of this library
is based on source code from JSR 166 and dl.util.concurrent, both very
well tested. Whenever possible, the JSR 166 code was used. In cases when
it was infeasible (e.g. the JSR 166 code had strong dependencies on
native JVM support), the dl.util.concurrent code was adapted. The new
code was introduced only when absolutely neccessary, e.g. to make
dl.u.c. code conforming to JSR 166 interfaces and semantics.
However, as any software, it may still contain bugs. I will conduct more
tests, but I would like to welcome everybody to try it out, report any
issues, or contribute source code. There is still a couple of things
missing (e.g. JSR 166 functionality that didn't make it to
java.util.concurrent yet, or some of things listed below), and I welcome
collaboration. The library is released to public domain and can be used
without acknowledgement and for any purpose.
While substantial effort was made to ensure reliability and conformance
to specifications, the library is provided AS IS and without any express
or implied warranty.
-------------------------------------------------------------------------------------------------------------------------
The detailed explanation of what JSR 166 functionality is not supported:
Condition:
long awaitNanos(long nanosTimeout) is not supported, since it cannot
accurately report remaining times with nanosecond precision.
boolean await(timeout) and boolean awaitUntil(Date), called on
conditions obtained from locks, may sometimes wake up spuriously. This
is allowed by the Condition specification. However, it causes them to
occassionally fail tck unit tests. Maybe the tests are too rigorous, or
maybe the semantics of conditions returned from lock classes in
java.util.concurrent are stronger than required by the specification.
Nevertheless, this implementation still conforms to the specification.
ReentrantLock:
the following monitoring methods are not supported: boolean
hasWaiters(Condition), int getWaitQueueLength(Condition), Collection
getWaitingThreads(Condition).
the following monitoring methods are supported only for fair locks:
boolean hasQueuedThreads(), int getQueueLength(), Collection
getQueuedThreads(), boolean isQueued().
ReentrantReadWriteLock:
this implementation is based on dl.u.c.
ReentrantWriterPreferenceReadWriteLock, and thus is a slight departure
from java.util.concurrent that does not specify acquisition order but
allows to enable/disable fairness. This implementation does not have a
single-parameter constructor allowing to specify fairness policy; it
always behaves like writer-preference lock with no fairness guarantees.
Bacause of these characteristics, this class is compliant with JSR 166
specification of non-fair reentrant read-write locks, while the exact
semantics of fair locks are not supported (and the appropriate
constructor is missing).
Also, the following instrumentation and status methods are not
supported: Collection getQueuedWriterThreads(), Collection
getQueuedReaderThreads(), boolean hasQueuedThreads(), boolean
hasQueuedThread(Thread), Collection getQueuedThreads(), boolean
hasWaiters(Condition), int getWaitQueueLength(Condition), Collection
getWaitingThreads(Condition).
Semaphore:
Atomic multi-acquires: tryAcquire(int permits) and tryAcquire(int
permits, long timeout, TimeUnit unit) are not supported.
The following platform-level functionality is unsupported:
System.nanoTime(), UncaughtExceptionHandlers
The following low-level concurrency classes are not supported:
LockSupport, AbstractQueuedSynchronizer.
The following "atomic" utilities are not supported:
Atomic[Integer,Long,Reference]FieldUpdater.
The following collection classes are not supported: LinkedList,
ConcurrentLinkedQueue.
Note on nanosecond precision: although nanoTime() is not supported, the
library strives to honor nanosecond timeouts, if such are requested, by
using two-parameter variant of Object.wait(). Note, however, that most
JVMs prior to 5.0 will round up the timeout to full milliseconds anyway.
I kindly ask members of JSR 166 expert group to straighten out any
inaccuracies that I may have made in the above description.
Regards,
Dawid Kurzyniec