[concurrency-interest] TheadLocal variable usage inReentrantReadWriteLock

Gregg Wonderly gergg at cox.net
Sat Dec 15 10:40:57 EST 2007

David Holmes wrote:
> Hi Rob,
> Yes this is a known issue in Java 6. I think there's been some 
> discussion on the list if you search the archive. Otherwise see:
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625723
> The number of RRWL used in an application was expected to be relatively 
> small given that their benefits only become apparent in certain 
> use-cases. So the ThreadLocal overhead wasn't expected to be a 
> significant issue.
> For Java 7 the best solution might be to make the read counts optional. 
> Other approaches are also being looked at.

Recently, I put together a class that uses PhantomReference, an active reference 
counter and a background ReferenceQueue polling thread to allow me to use GC 
reference based discards to free resources.  It's use involves creating a 
concrete implementation somewhere that will not create a reference chain in the 
used types.  For example you might define a class such as the following.

public class MyRefTracker extends ReferenceTracker<MyClass,ToBeFreedType> {
	public void released( ToBeFreedType freeMe ) {

Then, you might have a class which has some reference based cleanup that is 
needed where objects of type MyClass are passed around, and have an implicit 
reference to a ToBeFreedType instance.  You would probably declare a static 
instance such as

	private MyRefTracker track = new MyRefTracker();

Then, in your classes activities, where instances of MyClass come into being, 
you'd use

	MyClass inst;
	ToBeFreedType free = inst.somethingToGetReference();
	track.trackReference( inst, free );

to start tracking the lifecycle of the instances of MyClass and relate those to 
the corresponding instances of ToBeFreedType.

For me, this finally allows the features of finalization to actually be achievable.

ReferenceTracker utilizes an atomic counter to decide when the ReferenceQueue 
polling thread should be active.  That thread is not daemon so that it can 
actually recover all of the released objects before the JVM exits.

My usage came about from the use of smart proxies in a Jini application which 
carry a Lease object that allows some resources that the server has reserved for 
each smart proxy instance to be freed.  Timeouts would allow the Lease to be 
eventually canceled correctly.  The LeaseRenewalManager will be faithfully 
renewing the Lease to the server, and when the final reference goes away, the 
Lease needs to be canceled.   This allows the smart proxy to be used as a normal 
object without lifecycle being strewn throughout the code with everyone tracking 
who they passed a reference to.

Gregg Wonderly

More information about the Concurrency-interest mailing list