在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行操作。 但在有些情况下,synchronized不能保证多线程对共享变量的正确读写。例如类有一个类变量,该类变量会被多个类方法读写,当多线程操作该类的实例对象时,如果线程对类变量有读取、写入操作就会发生类变量读写错误,即便是在类方法前加上synchronized也无效,因为同一个线程在两次调用方法之间时锁是被释放的,这时其它线程可以访问对象的类方法,读取或修改类变量。 这种情况下可以将类变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立拷贝,不会出现一个线程读取变量时而被另一个线程修改的现象。
ThreadLocal api:
get() Returns the value in the current thread's copy of this thread-local variable.
initialValue() Returns the current thread's "initial value" for this thread-local variable.
remove() Removes the current thread's value for this thread-local variable.
set(T value) Sets the current thread's copy of this thread-local variable to the specified value.
get就是返回当前线程放入线程变量的数据
ThreadLocal<Map<String,Object>> params = new ThreadLocal<Map<String,Object>>()
Map<String,Object> map = params.get();
1、首先建立一个基本类,里面包含了ThreadLocal方法,如
public class ParamHolder {
private static ThreadLocal<Map<String,Object>> params = new ThreadLocal<Map<String,Object>>();
/**
* 增加参数
* @param key
* @param value
*/
public static void put(String key,Object value){
if( params.get() != null){
params.get().put(key, value);
} else{
Map<String,Object> data = new HashMap<String, Object>();
data.put(key, value);
params.set(data);
}
}
/**
* @param param
* <p>更新所有参数值,用新的替换老的 </p>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void putAllParams(Map param){
params.set(param);
}
/**
* 返回指定key的参数,类型进行了转换
* @param key
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getByKey(String key,Class<T> clazz){
if( params.get() == null){
return null;
}
return (T)( params.get().get(key));
}
/**
* 获取指定key的参数值,返回为Object,需要自己强转
* @param key
* @return
*/
public static Object getByKey(String key){
if( params.get() == null){
return null;
}
return params.get().get(key);
}
/**
* @return
*/
public static Map<String,Object> getAllParams(){
return params.get();
}
/**
* 清空保存的数据
*/
public static void clear(){
params.set( new HashMap<String, Object>());
}
}
2、由于数据是静态数据,在使用的时候可以直接调用
ParamHolder.put(“ANSWER_MAP” , answers);这样就可以吧当前线程的数据放到map当中
3、如果需要在当前线程获取数据,直接通过
ParamHolder.getByKey(“ANSWER_MAP”);获取数据
这样可以是一个基本的ThreadLocal使用