- Sept 3, 2007
- Version 3.1 released. Now includes versions for Java 6.0
- Nov 11, 2006
- Version 3.0 released. Now includes versions for Java 1.2, 1.3, 1.4, and 5.0 (sic!)
- Jun 4, 2006
- Version 2.2 released.
JSR 166 functionality is tied closely to the Java 5.0 Virtual Machine, and some aspects of it cannot be fully backported to older platforms. This section discusses these differences between the backport and JSR 166.
JSR 166 functionality is tied closely to the Java 5.0+ Virtual Machine, and some aspects of it cannot be fully backported to older platforms. This section discusses these differences between the backport and JSR 166.
Since user libraries cannot define classes in java.* packages, all the original package names have been prefixed with edu.emory.mathcs.backport. For instance, java.util.concurrent.Future becomes edu.emory.mathcs.backport.java.util.concurrent.Future.
Differences between releases
The backport is based on latest JSR 166 source code and thus includes functionality that has been added in Java 6.0. Pay attention to the "since" javadoc tags if a strict conformance with Java 5.0 is desired. Examples of "since 1.6" functionality include: deques, navigable maps and sets (including ConcurrentSkipList[Map,Set]), "newTaskFor" in AbstractExecutorService, "lazySet" in atomics, RunnableFuture and RunnableScheduledFuture, "allowCoreThreadTimeout" in ThreadPoolExecutor, "decorateTask" in ScheduledThreadPoolExecutor, MINUTES, HOURS, and DAYS in TimeUnit, and appropriate retrofits in collection classes.
Backport is developed carefully to retain link-time compatibility, i.e. it is generally safe to replace an old library JAR with a new one (with a possible exception of APIs based on beta releases, e.g. current "since 1.6" classes and methods). Serial compatibility (i.e. ability of one version to deserialize objects that has been serialized using a different version) is maintained on a best-effort basis, and not always guaranteed. Please see details below. (Note that concurrency tools are usually not intended for persistent storage anyway). Compile-time compatibility: applications using wildcard imports (e.g. java.util.* and edu.emory.mathcs.backport.java.util.*) may cease to compile with updated backport versions (containing new classes) due to import ambiguities. In such cases, you must dis-ambiguate imports (i.e. use explicit imports as appropriate) and recompile.
Notes for version 3.0-3.1: Link-time and serial compatibility is fully preserved.
Notes for version 2.2: Link-time and serial compatibility is fully preserved for "since 1.5" APIs. For "since 1.6" APIs, link-time and serial compatibility is preserved except for navigable maps and sets, which API has recently changed slightly in Java 6.0 beta.
Notes for version 2.1: Link-time compatibility is preserved fully. Serial compatibility is preserved except for the class ReentrantReadWriteLock.
Notes for version 2.0:
- the "concurrent.Concurrent" class has been removed as of backport 2.0.
- Serialized representations of several lock classes have changed between versions 1.1_01 and 2.0, as a result of certain bug fixes and performance improvements (see changelog). This means that locks and collections serialized with 1.1_01 will not be deserialized properly by 2.0.
Differences between versions for Java 1.2 - 1.3, 1.4, 5.0, and 6.0Within the same release, backport versions optimized for Java 1.2 - 1.3, 1.4, 5.0, and 6.0, are source-level and link-time compatible. That is, (1) sources compiled using one version will compile using another version, and (2) classes compiled with one version can be used with another version without recompiling. However, they are not serially compatible - that is, objects serialized using one version cannot be deserialized using another version.
Detailed listing of functionality that has not been backported is presented below.
Java 5.0 Syntax
Package java.util.concurrent exploits new language features introduced in Java 5.0. In particular, most API classes are generic types. In the backport, they have been flattened to standard, non-generic classes. Still, programs linked against the backport should compile with Java 5.0 (after changing package names). Nevertheless, you may want to consider gradually switching to using generics once you make the transition to Java 5.0, since it gives better compile-time type checking.
Method long awaitNanos(long nanosTimeout) is not supported, since the emulation cannot reliably report remaining times with nanosecond precision. Thus, it probably would be too dangerous to leave the emulated method in the Condition interface. However, the method is still available, for those who know what they are doing, in the util.concurrent.helpers.Utils class.
the following monitoring methods are supported only for fair locks: boolean hasQueuedThreads(), int getQueueLength(), Collection getQueuedThreads(), boolean isQueued(), boolean hasWaiters(Condition), int getWaitQueueLength(Condition), Collection getWaitingThreads(Condition).
The backport implementation for Java 1.2 - 1.3 and 1.4 is based on dl.util.concurrent class ReentrantWriterPreferenceReadWriteLock, and thus slightly departs from java.util.concurrent that does not specify acquisition order but allows to enable/disable fairness. The backport implementation does not have a single-parameter constructor allowing to specify fairness policy; it always behaves like writer-preference lock with no fairness guarantees. Because 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 thus not provided).
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).
Blocking atomic multi-acquires: acquire(int permits) and tryAcquire(int permits, long timeout, TimeUnit unit) are supported only for FAIR semaphores.
To emulate System.nanoTime(), not present on JVM < 5.0, the method nanoTime() is provided in the class dl.util.concurrent.helpers.Utils. On Java 1.4.2 and above, it attempts to use high-precision timer via sun.misc.Perf (thanks to Craig Mattocks for suggesting this). On older Java platforms, or when sun.misc.Perf is not supported, it falls back to System.currentTimeMillis(). In the Java 5.0 and 6.0 version, it delegates to System.nanoTime().
Class ThreadHelpers is provided to emulate certain aspects of Thread.UncaughtExceptionHandler.
Note on nanosecond precision timing
The backport strives to honor nanosecond timeouts, if such are requested, by using two-parameter variant of Object.wait() in Java 1.2 - 1.3 and 1.4 versions. However, most Java platforms will round up the timeout to full milliseconds anyway. In Java 5.0 and 6.0 versions, the backport uses native nanosecond APIs.
Low-level concurrency classes
The following classes are not supported: LockSupport, AbstractQueuedSynchronizer, AbstractQueuedLongSynchronizer.
Rationale: these classes depend on explicit JVM support, delegating to low-level OS concurrency primitives. There seems to be no simple way of emulating them without introducing prohibitive performance overhead.
The following "atomic" utilities are not supported: Atomic[Integer,Long,Reference]FieldUpdater.
Rationale: on many platforms, these utilities cannot be emulated without a prohibitive overhead, negating their usefulness.