How to test if a ThreadLocal has been initialized without actually doing that?

I want to test if a ThreadLocal has been initialized without actually initializing it. Of course, the code needs to be thread-safe. Ideally I want something like this:

class TestableThreadLocal<T> extends ThreadLocal<T> {
    public boolean isInitialized() {
        ...
    }
}

But how would I implement this method?

Edit: Motivation: I have subclassed a ThreadLocal to override initialValue() . However, I do not always need the initialization, in particular because it could cause a memory leak in multi-classloader environments. A simple test would help me write code to avoid the accidental initialization.


I tend to use simple rules to avoid classloader leaks, admittedly they are cumbersome but with some wrapping it's not that bad. Yes, leaks are evil.

  • do no override initialValue , ever - you are just asking for trouble, just forget it exists.
  • do not store non-system/non-bootstap classes in the ThreadLocal unless you do threadLocal.set(xxx); try{...process...}finally{threadLocal.set(null);} threadLocal.set(xxx); try{...process...}finally{threadLocal.set(null);}
  • if you still override initialValue, use threadLocal.remove() not threadLocal.set(null)
  • or use WeakReferene (ie ThreadLocal <WeakReference<Foo>> ) for the value from a pool that keeps the hard references. It might look counter intuitive but once the pool is cleared the values disappear and the classes are free to be GC'd
  • I realize the post is not a direct reply to your question, however there is no simple way to achieve what you wish and keep the leaks at bay.


    Thoughts:

  • if ThreadLocal.get is called, the value is initialized.
  • If you don't want it initialized, you don't need the value stored (at all, ever)
  • If you want to avoid the initialize, it seems the place to start is by overriding get , not initialValue .
  • taking a different track - do you really need to inherit ThreadLocal as opposed to containment?

  • One of the few possible ways of doing this would involve reflection as ThreadLocal does not have an API that lets you know whether the value has been initialized.

    It is certainly possible to "code" it using reflection. However, all the usual caveat applies. Your reflection code would be highly dependent on the implementation details of java.lang.ThreadLocal and its non-public members. The moment the JDK vendors change the implementation your code would break.

    链接地址: http://www.djcxy.com/p/19908.html

    上一篇: 为什么你会实施finalize()?

    下一篇: 如何测试一个ThreadLocal是否已经被初始化而没有实际执行?