5
我一直在阅读有关ThreadLocal,试图了解它是如何工作的,以及为什么我们需要它。ThreadLocal沉思(或:太阳的javadoc错了?)
到目前为止,我已经能够学到如下:
- 的ThreadLocal类允许线程级持有对象的1个实例
- 实例是通过覆盖初值创建()
- 实例实际上是存储在each thread's HashMap
- 甲常识使用例can be found here
一切似乎都很好,直到我试图运行从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
附:代码评论OT或点在欢迎的意见。
最好的,这个错误几乎是4岁。需要4年才能在Web服务器上修复HTML手册的错误。与此同时,有20个更新版本。令人惊叹...... – 2010-06-22 00:27:03
@Peter在更新版本中无法更改规范。您可以看到该错误实际上是在几年前修复的。 – 2010-06-22 00:42:10
感谢您的通知。 – 2010-06-22 06:01:06