没明白ThreadLocal的initialValue方法是怎样保证同步的,测试程序如下,确实每个线程都有一个本地的副本
但是各个线程第一次调用get或set的时候,initialValue方法是怎样保证同步的呢?如蓝色部分/*
 * file: ThreadLocalDemo.java
 * class: ThreadLocalDemo
 *
 * description: 
 *
 * @author:  leisore
 * @version: V1.0.0
 */
package cn.leisore.daily._2011_06_20;import java.lang.reflect.Array;
import java.util.Set;
import java.util.TreeSet;// ID counter, per id per thread
class ID {
// private static final ThreadLocal<Integer> threadLocal = new
// ThreadLocal<Integer>() {// 1
private final ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
int initId = 0; @Override
protected Integer initialValue() {
return initId = initId + 1;
}
}; public ID() {
// private ID() {
} // public static final int id() {//1
public final int id() {
return threadLocal.get();
}
}public class ThreadLocalDemo {
public static void main(String[] args) { final ID id = new ID(); final Thread[] threadArr = new Thread[10];
@SuppressWarnings("unchecked")
final Set<Integer>[] threadIdSetArr = (Set<Integer>[]) Array
.newInstance(Set.class, threadArr.length); for (int i = 0, j = threadArr.length; i < j; i++) {
final int threadIndex = i;
threadIdSetArr[threadIndex] = new TreeSet<Integer>();
threadArr[i] = new Thread(String.valueOf(threadIndex)) {
int myIndex = threadIndex; @Override
public void run() {
for (int k = 0; k < 100; k++) {
threadIdSetArr[myIndex].add(id.id());
}
}
};
} // start
for (Thread t : threadArr) {
t.start();
} // wait until all were done
for (Thread t : threadArr) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} for (int i = 0, j = threadIdSetArr.length; i < j; i++) {
System.out.println(String.format("Thread %d: %s", i,
threadIdSetArr[i].toString()));
}
}
}
输出:
/*
Thread 0: [1]
Thread 1: [6]
Thread 2: [2]
Thread 3: [7]
Thread 4: [3]
Thread 5: [8]
Thread 6: [4]
Thread 7: [9]
Thread 8: [5]
Thread 9: [10]
*/

解决方案 »

  1.   

    颜色没显示出来:
     public final int id() {
            return threadLocal.get();
     }

    threadIdSetArr[myIndex].add(id.id());
      

  2.   

    嗯,比较了一下1.5和1.6的doc中例子
    1.5使用了synchronized,而1.6使用了原子变量
    看来initialValue方法确实需要同步,以确保各线程可以得到正确的初始值
    看看大家还有什么其他的结论没,明晚结贴
    我的例子没有测出来,是机器太差了么