Я читал о ThreadLocal, пытаясь понять, как он работает и зачем он нам нужен.
Пока что я смог выучить следующее:
- Класс ThreadLocal позволяет хранить 1 экземпляр объекта на уровне потока
- Экземпляр создается путем переопределения initialValue ()
- Экземпляр фактически сохраняется в HashMap каждого потока
- Пример использования здравого смысла можно найти здесь
Все выглядело нормально, пока я не попытался запустить пример из javadoc, код предоставляется следующим образом:
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal < Integer > uniqueNum =
new ThreadLocal < Integer > () {
@Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueId.get();
}
} // UniqueThreadIdGenerator
Если я правильно понимаю этот код, вызов getCurrentThreadId () должен вернуть правильный автоматически увеличенный номер потока, увы, он возвращает 0 для меня.ВСЕГДА 0, без учета того, сколько потоков я запустил.
Чтобы это работало для меня, мне пришлось изменить getCurrentThreadId (), чтобы читать
public static int getCurrentThreadId() {
return uniqueId.get();
}
В этом случае я получаю правильныйзначения.
Мой код указан ниже, что мне не хватает?(Дело не в том, что Javadoc на самом деле не прав, не так ли?)
package org.vekslers;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator extends Thread {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal <Integer> uniqueNum =
new ThreadLocal <Integer> () {
@Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueNum.get();
}
//////////////////////////////////////////////////
// Testing code...
//////////////////////////////////////////////////
private static volatile boolean halt = false;
public UniqueThreadIdGenerator(String threadName) {
super(threadName);
}
@Override
public void run() {
System.out.println(Thread.currentThread() + " PREHALT " + getCurrentThreadId());
while(!halt)
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " POSTHALT " + getCurrentThreadId());
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new UniqueThreadIdGenerator("t1");
Thread t2 = new UniqueThreadIdGenerator("t2");
Thread t3 = new UniqueThreadIdGenerator("t3");
Thread t4 = new UniqueThreadIdGenerator("t4");
t3.start();
t1.start();
t2.start();
t4.start();
TimeUnit.SECONDS.sleep(10);
halt = true;
}
} // UniqueThreadIdGenerator
Вывод:
Thread[t3,5,main] PREHALT 0
Thread[t1,5,main] PREHALT 1
Thread[t2,5,main] PREHALT 2
Thread[t4,5,main] PREHALT 3
Thread[t4,5,main] POSTHALT 3
Thread[t2,5,main] POSTHALT 2
Thread[t1,5,main] POSTHALT 1
Thread[t3,5,main] POSTHALT 0
ps Комментарии к кодам OT или в точку приветствуются в комментариях.