Threadlocal 记事
Threadlocal 简单介绍:
ThreadLocal的实例代表了一个线程局部的变量,每条线程都只能看到自己的值,并不会意识到其它的线程中也存在该变量。
它采用空间来换取时间的方式,解决多线程中相同变量的访问冲突问题。
Threadlocal 简单应用:
1.工具类
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings(“unchecked”)
public final class ThreadLocalUtil {
private static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>() {
protected Map<String, Object> initialValue() {
return new HashMap<String, Object>();
}
};
public static <T> T get(String key, Class<T> clazz) {
Map<String, Object> map = (Map<String, Object>)threadLocal.get();
return (T)map.get(key);
}
public static Object get(String key) {
Map<String, Object> map = (Map<String, Object>)threadLocal.get();
return map.get(key);
}
public static void set(String key, Object value) {
Map<String, Object> map = (Map<String, Object>)threadLocal.get();
map.put(key, value);
}
public static void remove() {
threadLocal.remove();
}
public static <T> T remove(String key) {
Map<String, Object> map = (Map<String, Object>)threadLocal.get();
return (T)map.remove(key);
}
}
实例:
ThreadLocalUtil.set(“MEMBERSHIP”, membership);
membership = (MembershipPO)ThreadLocalUtil.get(YeepayProxyConstants.MEMBERSHIP);
2.作为传递参数的工具,进行参数传递
3.保证线程安全不受影响
Threadlocal 原理
1.Thread类中有一个成员变量属于ThreadLocalMap类(一个定义在ThreadLocal类中的内部类),它是一个Map,他的key是ThreadLocal实例对象。
2.当为ThreadLocal类的对象set值时,首先获得当前线程的ThreadLocalMap类属性,然后以ThreadLocal类的对象为key,设定value。get值时则类似。
ThreadLocal变量的活动范围为某线程,是该线程“专有的,独自霸占”的,对该变量的所有操作均由该线程完成!也就是说,ThreadLocal 不是用来解决共享对象的多线程访问的竞争问题的,因为ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。当线程终止后,这些值会作为垃圾回收。
3.由ThreadLocal的工作原理决定了:每个线程独自拥有一个变量,并非是共享的。
可以理解为为每个线程创建了一个map ,彼此独立 ,在线程中可以获取map 内的 数据结构 而不影响线程安全。
注意
当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在ThreadLocalMap<null, Object>的键值对,造成内存泄露。(ThreadLocal被回收,ThreadLocal关联的线程共享变量还存在)。
1、使用完线程共享变量后,显示调用ThreadLocalMap.remove方法清除线程共享变量;
2、JDK建议ThreadLocal定义为private static,这样ThreadLocal的弱引用问题则不存在了。
3.使用完对象,要及时remove掉,注意创建的时机