[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