Java线程:深入ThreadLocal
2010-01-22 00:00:00 来源:WEB开发网运行测试:
Thread-0 1
Thread-0 2
Thread-0 3
Thread-2 1
Thread-2 2
Thread-3 1
Thread-2 3
Thread-3 2
Thread-1 1
Thread-3 3
Thread-1 2
Thread-1 3
Process finished with exit code 0
很意外,这个山寨版的ThreadLocal也同样运行很好,实现了JavaAPI中ThreadLocal的功能。
四、透过现象看本质
其实从程序角度看,tlt变量的确是一个,毫无疑问的。但是为什么打印出来的数字就互不影响呢?
是因为使用了Integer吗?-----不是。
原因是:protected T initialValue()和get(),因为每个线程在调用get()时候,发现Map中不存在就创建。调用它的时候,就创建了一个新变量,类型为T。每次都新建,当然各用个的互不影响了。
为了看清本质,将Integer换掉,重写部分类:
package com.lavasoft.test2;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* 使用了ThreadLocal的类
*
* @author leizhimin 2010-1-5 10:35:27
*/
public class MyThreadLocal {
//定义了一个ThreadLocal变量,用来保存int或Integer数据
// private ThreadLocal<Bean> tl = new ThreadLocal<Bean>() {
private com.lavasoft.test2.ThreadLocal<Bean> tl = new com.lavasoft.test2.ThreadLocal<Bean>() {
@Override
protected Bean initialValue() {
return new Bean();
}
};
@Override
public String toString() {
return "MyThreadLocal{" +
"tl=" + tl +
'}';
}
public Bean getBean() {
return tl.get();
}
}
class ThreadLocal<T> {
private Map<Thread, T> map = Collections.synchronizedMap(new HashMap<Thread, T>());
public ThreadLocal() {
}
protected T initialValue() {
return null;
}
public T get() {
Thread t = Thread.currentThread();
T obj = map.get(t);
if (obj == null && !map.containsKey(t)) {
obj = initialValue();
map.put(t, obj);
}
return obj;
}
public void set(T value) {
map.put(Thread.currentThread(), value);
}
public void remove() {
map.remove(Thread.currentThread());
}
}
更多精彩
赞助商链接