ThreadLocal
软引用
1.对象回收是可以跟踪的,finallize()方法
对象被回收时,会调用finallize方法
2.System.in.read()//阻塞main线程,给垃圾回收线程时间执行
①main线程退出,垃圾回收线程也随即退出,可能对象未回收玩,就已退出
②③
3.变量只能是强引用,要想软引用,得变量–>软(逻辑中的软)引用对象–>堆中对象
SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 10])
4.软引用其实非常简单(堆总共20M,先new 10M软 ,再new 15M强)
内存不够时,会被回收,内存够时会回收。(垃圾回收一次后,任然不够,回收软引用指向的内存)
5.强引用,宁可溢出,也不会回收你
6.软引用有什么用:非常适合来做缓存(内存够的话先在里面呆着)
弱引用
WeakReference<M> m = new WeakReference<>(WeakReference<M> m = new WeakReference<>(new M());
虚引用(NIO NETTY)
作用:管理直接内存
直接内存:JVM可以通过一个指针访问操作系统内存,如果从网络来的数据,就不用再拷贝一份了。
ThradLocal
1.Spring中多个方法嵌套调用,都要支持事务,那么数据库连接对象得是同一个
数据库连接对象不能是不同的,不能是全局的,全局的话就只有1个连接了。
Spring怎么传连接对象的,通过ThreadLocal
2.demo不同线程访问共享的静态变量 ThreadLocal,1个线程放入的,另一个线程取不出来
和线程绑定的,不同线程间隔离。
3.上面的原理,分析源码
每1个线程对象中都有1个ThreadLocalMap类的成员变量,指向一个map
ThreadLocal的set方法是以自己的引用为key,参数为value,存入当前线程的ThreadLocalMap中
Entry是理解的关键,是ThreadLocal的静态内部类,是WeakReference的子类
ThreadLocalMap的get 和set 会remove所有key为null的Entry,还需要手动remove Entry吗?
要的,因为有服务器线程7 * 24 运行,可能不执行get,set方法,这样做可以防止Entry内存泄露。
- 如果是线程池的话,线程用完,要清除threadlocal. 以防下次用时,可能用的是旧值。
强引用:默认的。
软引用:缓存;
弱引用:防内存泄露
虚引用:jvm管理直接内存用的
ThreadLocal如何使得一个线程只有1个Looper?
1.Looper是如何创建的?
Looper.prepare();
public final class public final class Looper {
static final ThreadLocal sThreadLocal = new ThreadLocal();
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
}
2.不同线程访问共享静态变量sThreadLocal,调用set方法,以共享的ThreadLocal
类的对象的引用为key,以new的Looper对象对Value。它是往当前线程的ThreadLocalMap
中存入key,value的;
不同线程通过get取时,拿到的是自己线程的Looper
3.多线程访问共享静态变量sThreadLocal, 1个线程存的东西,另一个线程取不到,起到了线程隔离的作用。
4.ThreadLocalMap中有一个Entry数组,key为什么要继承自弱引用呢?
因为sThreadLocal至空之后,线程Entry的属性key任然持有ThreadLocal的引用,value也不能释放。会有内存泄露的问题
ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,如何防止自己的变量被其它线程篡改。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!