Я читал о ThreadLocal, пытаясь понять, как он работает и почему нам нужен он.
До сих пор то, что я смог изучить, следующее:
Весь казался прекрасным, пока я не пытался выполнить пример от 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 uniqueNum =
new ThreadLocal () {
@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
p.s. Комментарии к коду OT или к точке приветствуются в комментариях.
Документы javadoc неверны.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6475885
javadoc Java 7 включает
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadId {
// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
@Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}