用过Spring的可能都知道,Spring将Dao层的JavaBean可以设置成Singleton并生成这个Singleton的实例。但是Singleton的JavaBean应该是无状态的(另外的一个意思就是这个JavaBean是
线程安全的),但是数据库操作是有状态的,比如Connection对象就是有状态的,应该对于每个执行数据库操作的每个线程都有一个Connection对象。那如何用Singleton实例实现
线程安全呢。答案就是ThreadLcoal。
ThreadLcoal是从JDK1.2被引入的。ThreadLcoal它不是线程,而是线程的一个本地化对象。当工作于多线程的对象使用ThreadLcoal维护变量时,ThreadLcoal会为每个使用该变量的线程分配一个独立的变量副本,所以每一个线程都可以独立改变自己的副本,而不会影响其他的线程。
那么ThreadLcoal是如何实现上述工作的呢,ThreadLocal中维护了一个map结构,该map结构的key是当前线程,value值是对应线程的变量副本。照着这个意思,也可以实现自己的一个ThreadLcoal。ThreadLcoal中主要的方法有一下几个,set方法,get方法 remove方法 initialValue方法。相信看了以下ThreadLcoal的简单实现,这些代码的意思也就不难
理解了。
class="java">import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class MyThreadLocal {
private Map valueMap= Collections.synchronizedMap(new HashMap());
public void set(Object newValue){
valueMap.put(Thread.currentThread(), newValue);
}
public Object get(){
Thread currentThread=Thread.currentThread();
Object o= valueMap.get(currentThread);
if(null==o&&!valueMap.containsKey(currentThread)){
o=initalValue();
valueMap.put(currentThread, o);
}
return o;
}
public void remove(){
valueMap.remove(Thread.currentThread());
}
public Object initalValue(){
return null;
}
}
那么ThreadLocal与传统的线程
同步机制有什么不同点呢?
1、ThreadLocal以空间换时间,利用为每一个线程都维护一个非线程安全的变量的一个副本实现并发的目的,用空间的增加来换取快速的处理时间。
2、传统的线程同步机制正好相反,是利用时间来换取空间,通过多个线程只维护一个非线程安全的变量,通过对该变量进行访问控制(例如synchronized)来实现线程安全,空间利用的少,但是处理时间也相应的长了。