Proposed new Java feature

R

Robert Klemme

Naw, I just disagree. Saying that the creator is responsible for cleanup
is like saying that because some objects need an explicit "close," we
should force those semantics onto all objects.

The cleanup method does not need to be overridden - that's why I did not
make it abstract. There is no semantic forced on all objects.

Also, I don't see the implication: If clearing references is sufficient
then that's perfectly OK. But, as you noticed, there are objects which
require some explicit cleanup. Only the author of the code which
creates a ThreadLocal can know how it must be cleaned up. With the
global reference nulling you are actually forcing semantics on all
because then there is just this one way. Since
ThreadLocal.initialValue() is there for custom initialization, it's as
reasonable to provide a hook for resource deallocation code. (Btw.,
that's the same pattern callback interfaces for object pools employ.)

If one does not want the cleanup hook for all ThreadLocals, one can
place the cleanup functionality in a sub class of ThreadLocal thus not
affecting existing code at all.
If you have a thread local that requires special semantics, go ahead and
provide the special code for those objects. The rest of the code can use
a common cleanup up mechanism that MOST objects require: just GC them.

The point is that with the global reference cleanup the specific code
does not have a chance to run because it does not know when. The proper
point in time is just before or during remove().

Kind regards

robert
 
M

Mike Schilling

Robert Klemme said:
The point is that with the global reference cleanup the specific code does
not have a chance to run because it does not know when. The proper point
in time is just before or during remove().

How would the cleanup code knew when to run during Thread exit?
 
A

Andreas Leitgeb

Mike Schilling said:
Note that it makes your objections moot. There's no way to enforce that the
called code be "correct", and there is no invoker to worry about.

Eric and Daniel's "issues" were as nonsensical as arguing against file
removal, for the risk of *all* the bytes of the file being lost as a
consequence.
We're *not* talking of deleting all files of the system, as that would
correspond to delete *every* threads' ThreadLocals.

The whole point of the proposal is to remove *all* the data attached to
one respective thread under circumstances where that data would no longer
be relevant to the thread. If some code relied on persistence of Thread-
Local data across two threads obtained from a pool-thread, then this code
is already broken. And if one wants a cache that survives a single use
of a pool thread, then ThreadLocal would be a really goofy choice for it
(with or without the proposed feature).

Finally, the route of crude workarounds has already been entered by using
thread pools in the first place. In an ideal world, one would allocate
threads and discard them, and have the reuse of OS threads implemented
under the jvm hood, just like with memory.
 
R

Robert Klemme

How would the cleanup code knew when to run during Thread exit?

Obviously that would have to be implemented in class Thread using a
finally block.

robert
 
K

Kevin McMurtrie

Mike Schilling said:
First a few observations:

1. ThreadLocals may be, in general, an abomination, but there are situation
where they're the least of evils. And if you're building a framework in
which third-party code runs (e.g. a webserver), there's no way to disallow
their use.

2. ThreadLocals interact badly with ThreadPools, because the ThreadLocals
keep their value when the tyhread is put back into the pool. This can lead
to leaks and even potential security issues.

3. The current implementation of ThreadLocal is this: each thread contains a
map from the ThreadLocal instance to its value for that thread. (This is
slightly less intiutive than giving a ThreadLocal instance a map from Thread
to value, but has the advantage that the map, which is only used within one
thread, needn't be synchronized.)

Proposed feature: a static method on Thread that clears all ThreadLocals for
the current thread. By 3 it's trivial to implement. By 1 and 2 it's
needed. And ThreadPool implementations can simply call it directly before
putting the Thread back into the pool.

I find ThreadLocal useful for caching rapidly used utility objects that
are stateful and expensive to initialize. Formatters, regexp parsers,
etc. Despite that use, I do still hate the way ThreadLocal works.

A built-in ThreadLocalCache would be better. It would behave like
ThreadLocal except use a SoftReference for each element. That would
save me the trouble of writing my own when the thread count gets to be
too high for having a few KB idle in each thread. (It would be nice if
SoftReference behaved better too)

Forcing the ThreadLocals out of a Thread would be bad. There's still
too much crap code floating around that uses ThreadLocal for parameter
passing. You'd get too much random behavior that's nearly impossible to
debug. It would be no worse to eliminate ThreadLocal support entirely.
 
M

markspace

Forcing the ThreadLocals out of a Thread would be bad. There's still
too much crap code floating around that uses ThreadLocal for parameter
passing.


Just because there's "crap out there" doesn't mean a new feature isn't
useful or a good idea. No one requires you to call "removeLocals" or
whatever method in your code. Obviously, no "crap out there" currently
calls such a method, unless you're willing to muck with reflection. So
what harm does adding something useful do? That someone *might* use it
inappropriately? Come on, that describes every single method in the
Java API.
 
V

Volker Borchert

Mike said:
1. I create a new thread to handle each new request.
2. I optimize (1) by using a thread pool to minimize thread creation.

I want those two to behave identically (other than performance). To acheive
that, I need to be able to kill all the ThreadLocals when putting the
Threads back into the pool for later reuse. Otherwise

Your threads should know which ThreadLocal they have used, so you
should be able to get away with ThreadLocal.remove().

I would perhaps subclass Thread to PoolableThread and therein define
a method reset() or something, which will call that method for all
known used ThreadLocal, and clear other semi persistent state. This
method would be called when returning the PoolableThread to the pool.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top