[concurrency-interest] Soliciting input about removeAllThreadLocals

Doug Lea dl@cs.oswego.edu
Fri, 6 Dec 2002 06:54:32 -0500


Dear concurrency-interest list members,

We in the expert group have been periodically arguing about the
proposed Thread.removeAllThreadLocals method.  This method erases ALL
of the ThreadLocals associated with a thread, so that the next time
access of any of them is attempted, its initialValue() is returned.

The main issues are:

 *  Supporting removeAllThreadLocals provides an (optional) way to
    prevent tasks run by worker Threads in Executors (i.e., mainly,
    ThreadExecutor) from using "leftover" values of ThreadLocals from
    previous tasks, which will likely be the source of subtle bugs.
    Normal use here would be to call removeAllThreadLocals in one or
    more ExecutorIntercepts methods when you'd like to prevent such
    problems. This way, each task runs under a worker thread just like
    it would under a new Thread, except that the thread is actually
    the same one as used for a previous task.

 *  But having such a method is otherwise a potential breach of
    encapsulation, and could cause problems with other
    classes/componentss expecting their ThreadLocals to forever be
    associated with threads, even worker threads that perform many
    unrelated tasks.

The question is, which is worse, 
  (1) unexpected reuse, 
or 
  (2) unexpected clearing. 

Specifically, is (2) such a serious problem that removeAllThreadLocals
shouldn't be supported, forcing people to live with (1), or to not use
ThreadExecutors when this problem arises?

To alleviate (2), if we keep the capacity for removing all
ThreadLocals, we will probably restructure things with the net effect
that this can be done only for worker threads within Executors, not
for arbitrary Threads.

Note that if you know of a particular problematic ThreadLocal, you can
always either invoke ThreadLocal.set(null) or better, the new
ThreadLocal.remove() method on it to clear it from within executor
intercepts. The removeAllThreadLocals method differs here in that it
also clears those ThreadLocals that the Executor does not otherwise
know about.

We'd like to collect experiences about this. (Not opinions -- we have
equally strong "over my dead body" views on each side of this already
in the expert group!).  If you are currently using some kind of thread
pool (perhaps dl.u.c.PooledExecutor), and/or programs that make heavy
use of ThreadLocals, please tell us if:

   * You have encountered problems due to leftover ThreadLocals
     spilling over across tasks performed by the same thread.
Or

   * You have code that would break if run via ThreadExecutors that
     cleared all ThreadLocals between tasks.

Or related horror stories surrounding ThreadLocals.

Thanks very much!

-- 
Doug Lea, Computer Science Department, SUNY Oswego, Oswego, NY 13126 USA
dl@cs.oswego.edu 315-312-2688 FAX:315-312-5424 http://gee.cs.oswego.edu/