我正在寻找一个类似于ThreadLocal的类,它可以在线程组而不是线程上工作。
如果没有这样的类(在某些开源库中),你会如何实现它?比在WeakHashMap中拥有线程组更好的想法吗?
我在运行时实现一个可调整的调试框架,其中包含全局,每线程和每线程组上下文中的各种参数。作为一个非常简单的示例,您可以使用报告声明:
debug.log( category, message);
并指定仅当由服务于网络请求的线程组中的线程调用时,才会显示具有该特定类别的日志条目。
答案 0 :(得分:5)
ThreadGroup
很少使用,因此没有平台支持。
使用[Weak
/ Identity
/ Concurrent
] HashMap<ThreadGroup,T>
即可开展工作,如果不是很快的话。你真的希望地图都是弱的,身份和并发的,但是对于Java库,你现在只能选择一个。
要提高效果,请注意Thread
不会更改ThreadGroup
。因此,使用ThreadLocal
缓存该值(覆盖initialValue
)。 ThreadLocal
表现良好(每get
个十几个周期)。
答案 1 :(得分:5)
我会将一个值持有者存储在本地线程中,并将其初始化为同一组中所有线程的相同值持有者。
public class ThreadGroupLocal<T> extends ThreadLocal<ValueHolder> {
private static class ValueHolder {
public Object value;
}
// Weak & Concurrent would be even the better, but Java API wont offer that :(
private static ConcurrentMap<ThreadGroup, ValueHolder> map = new ConcurrentHashMap<ThreadGroup, ValueHolder>;
private static ValueHolder valueHolderForThread(Thread t) {
map.putIfAbsent(t.getThreadGroup(), new ValueHolder());
return map.get(t.getThreadGroup());
}
@Override
protected ValueHolder initialValue() {
return valueHolderForThread(Thread.currentThread());
}
public T getValue() { (T) get().value; }
public void setValue(T value) { get().value = value; }
}
然后使用
ThreadGroupLocal<String> groupLocal = new ThreadGroupLocal<String>();
groupLocal.setValue("foo");
//...
String foo = groupLocal.getValue();
确实(期望初始化)与本地线程完全相同。
答案 2 :(得分:2)
我最后一次查看实现(几年前)Thread Locals是作为一个由线程id索引的简单哈希表实现的。没有什么花哨的,远离C ++的效率。
您也可以这样做,并使用线程组对象作为您自己的线程组本地哈希表的键。