views:

55

answers:

2

Context:

static ThreadLocal<MyType> threadLocalMyType = ...

What i'd like is to say something like:

for (ThreadLocalEntry e: threadLocalMyType.getMapLikeThing() {
    // Thread t = e.getKey(); 
    // I don't need the thread value right now, but it might be useful for 
    // something else. 

    MyType theMyType = e.getValue();
    // [...do something with theMyType...]
}
+2  A: 

One way would be to handle this manually:

  • use a wrapper of ThreadLocal (extend it)
  • whenever a value is set, keep a (static) Map of Threads and values

Alternatively, with some reflection (getDeclaredMethod() and setAccessible(true)), you can:

  • call Thread.getThreads()
  • call yourThreadLocal.getMap(thread) (for each of the above threads)
  • call map.getEntry(yourThreadLocal)

The 1st is more preferable.

Bozho
I guess, in short, that the answer to the question is 'No', and the solution for me would be simply "static ConcurrentHashMap<Thread, MyType>"...although that forsakes the optimization of ThreadLocal.
Jonas N
Thanks for the discussion, doublep and Bozho; if I had reps...I'll accept the Bozho answer because it outlines two solutions, although since I don't _have_ to use ThreadLocal I'll go with a ConcurrentHashMap instead.
Jonas N
@Jonas: If you use your `ThreadLocal` mostly for getting and not for setting, you could have it both way. As I understand that's what Bozho proposed: when _setting_ a value, also duplicate it in some other map. Then the thread can _get_ from `ThreadLocal` (efficiently), while other threads could read from the synchronized (and thus less efficient) secondary storage. Though if that value points to some object, consider if access to it needs additional synchronization.
doublep
Yes, it's strictly for getting, so it would indeed be more efficient. And yes, I think I can't avoid the synchronization; because at the 'interval activation points' (what to call it :) the MyType would be mutated (a list is emptied or replaced with empty list). I think the price of the synchronization would be quite low though, since contention could only happen at those points. And I shouldn't overengineer like this :)
Jonas N
+1  A: 

No, because internally it is implement differently: each thread has a map-like thing of its locals. What you want to do would be inherently thread-unsafe if ThreadLocal allowed it. Each thread obviously doesn't use any kind of synchronization when accessing its own locals: no other thread can do that, so synchronization is not needed. For this reason, accessing the locals map from any other thread (if that was possible) would be thread-unsafe.

As Bozho suggested, you could do that by subclassing ThreadLocal and duplicating values somewhere else. Don't forget to synchronize access to that "somewhere else" properly.

doublep
I realize the class is for a single purpose, thread-local objects; so one can't really blame the ThreadLocal designer/s for not including a mechanism to do what I want here (I'm pretty sure it could be done thread-safely, but would likely incur lowered optimization, and it kind of conflicts with the name 'Local', as I interpret what you said above). I hadn't understood it fully before asking the question, I'm afraid.
Jonas N
Yes, as I see `ThreadLocal` could implement this feature, but then it would have to synchronize access to the internal map, thus adding unneeded overhead for the common case.
doublep
Let's propose a ThreadGlocal for Java-7...
Jonas N