Re: Proposed new Java feature
On 05/28/2012 12:27 AM, Tom Anderson wrote:
On Sun, 27 May 2012, Eric Sosman wrote:
If you think of anything new to add, pray do so.
Mike added this pithy statement of the goal:
Or, to say it another way, when getting a Thread from a ThreadPool, it
should be completely indistinguishable whether it's a recycled or
brand-new thread.
At the moment, it is *not* possible to achieve that, because
ThreadLocals will survive recycling.
But that is actually a good thing: ThreadLocal's purpose is to attach
state to a thread which can be accessed without synchronization (if not
shared). Consider attaching a database connection to a thread. It
would be disastrous for the connection itself to just clear the object
reference through some global "remove all" and you would pay a high
price for opening new connections over and over again. If the database
connection is supposed to be attached to a thread for only a certain
amount of time (e.g. a method call) then it must be coded to be properly
cleaned up; in case of a JDCB connection that means invoking commit() or
rollback() and then close(). Only after that you can safely clear the
reference. But this entirely depends on the ThreadLocal at hand and
needs to be done specifically for individual ThreadLocals - it cannot be
done globally.
One way of looking at a thread pool is that it provides a supply of
fresh short-lived virtual threads, implemented on top of long-lived real
threads. Every time we take a thread out of the pool, we want it to
appear brand-new. Deleting all ThreadLocals when a real thread is
recycled is not "extremely dangerous", because at that moment, the
*virtual* thread is dying, and a new one is being created; that makes it
an entirely appropriate thing to do.
It *is* dangerous as I have explained above. The observable state of
each of these virtual threads should of course be identical but that
does not mean that the technical state must be identical (that's
basically what caching is all about). For example, in case of the DB
connection you might open the connection in initialValue() or some other
logic so the code using the ThreadLocal always sees a properly
initialized connection.
It is certainly true that it is "only a crutch for not doing the right
thing to begin with", but the sad fact is that programmers persist in
not doing the right thing to begin with, and it is useful for framework
writers to be able to limit the damage they can cause.
Actually the global remove would cause more damage than it prevents.
You cannot know about all the other ThreadLocals used in code and a
framework writer who attempts to just clear state of other modules
without even knowing them should be tarred and feathered.
Cheers
robert