线程本地变量
最常见的ThreadLocal(是个对象)使用场景为 用来解决 数据库连接、Session管理等。
在多线程的环境中,在不对connection做线程安全处理的情况下,使用单个connection会引起事务的混乱影响jdbc事务的使用.ThreadLocal提供了get和set访问器,为每个使用它到线程维护一份单独到拷贝。get总能返回由当前执行线程通过set设置的最新值。
ThreadLocal关键源码:
public void set(T value) {
Thread t = Thread.currentThread();//当前线程对象
ThreadLocalMap map = getMap(t);//当前线程Thread的ThreadLocalMap数据结构
if (map != null)
map.set(this, value);//key是当前ThreadLoad对象,value是T存储在t.ThreadLocalMap下
else
createMap(t, value);//如果当前线程到ThreadLocalMap为null则初始化一个
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals; //返回到是Thread对象内部数据结构ThreadLocal.ThreadLocalMap threadLocals = null;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
Java强弱虚引用
Object o=new Object(); // 强引用当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
SoftReference<String> softRef=new SoftReference<String>(str); // 软引用是用来描述一些有用但并不是必需的对象,用于缓存内存满了会gc回收。
WeakReference<String> abcWeakRef = new WeakReference<String>(str);//弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。一次性
虚应用,JVM gc管理堆外内存(NIO)zero copy,清理后写入queue单独起线程清理堆外内存。
防止内存泄露OOM,线程对象的ThreadLocalMap的key是ThreadLoacl对象的引用(弱引用),线程结束ThreadLocal可正常GC回收。
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k); //弱引用
value = v;
}
}