Я ищу класс, подобный ThreadLocal, который работал бы над группами потока вместо потоков.
Если бы нет такого класса (в некоторой библиотеке с открытым исходным кодом), как Вы реализовали бы его? Некоторая лучшая идея, чем наличие групп потока в WeakHashMap?
Я реализую платформу отладки, настраиваемую во времени выполнения с различными параметрами в глобальных, контекстах группы на поток и на поток. Как очень простой пример, у Вас может быть оператор создания отчетов:
debug.log( category, message);
и определите, что запись в журнале, с которой определенная категория будет отображена только при вызове потоком в группе потоков, обслуживающих сетевые запросы.
Я бы сохранил держатель значения в локальном потоке и инициализировал его одним и тем же держателем значения для всех потоков одной группы.
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();
. Это (за исключением инициализации) работает точно так же, как локальный поток.
В последний раз, когда я смотрел на реализацию (несколько лет назад) Локальные переменные потока были реализованы как простая хеш-таблица, индексированная по идентификатору потока. Ничего особенного и далеко от эффективности C ++.
Вы можете сделать то же самое и использовать объект группы потоков в качестве ключа для хеш-таблицы локальных переменных вашей собственной группы потоков.
ThreadGroup
используется редко, поэтому нет поддержки платформы.
Использование [ Weak
/ Identity
/ Concurrent
] HashMap
будет работать, если не очень быстро . Вы действительно хотите, чтобы карта была слабой, идентичной и параллельной, но в настоящее время с библиотекой Java вы можете выбрать только одну.
Для повышения производительности обратите внимание, что Thread
не изменяют ThreadGroup
. Поэтому кэшируйте значение с помощью ThreadLocal
(переопределите initialValue
). ThreadLocal
имеет хорошую производительность (пара десятков циклов на get
).