多线程与高并发四:VarHandle与强软弱虚引用和ThreadLocal

文章目录

  • 1:VarHandle
  • 2:强软弱虚引用
    • 2.1. 强引用
    • 2.2. 软引用(SoftReference)
    • 2.3. 弱引用(WeakReference)
    • 2.4. 虚引用(PhantomReference):管理堆外内存
  • 3:ThreadLocal
    • 3.1:线程本地
    • 3.2:原理
    • 3.3:ThreadLocal与弱引用的配合使用,解决内存泄露

1:VarHandle

上一篇说了AQS的源码,其中还有一个知识点VarHandle,看下面的代码
多线程与高并发四:VarHandle与强软弱虚引用和ThreadLocal_第1张图片
大家会问:VarHandle是什么?有什么作用?
其实:VarHandle是jdk1.9之后才出现的,表示指向某个变量的引用,可以完成原子性的线程安全操作可以通过cas方式进行比较设值。比反射快,直接操纵二进制码,反射每次操作前都要做检查

2:强软弱虚引用

博客部分内容引用:http://blog.csdn.net/liuxian13183

2.1. 强引用

Object object=new Object();那object就是一个强引用了。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题

2.2. 软引用(SoftReference)

如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

2.3. 弱引用(WeakReference)

一般用在容器里WeakHashMap 还有ThreadLocal 。 如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

2.4. 虚引用(PhantomReference):管理堆外内存

"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。NIO里面的PirectByteBuffer指向堆外内存,被称为直接内存,由操作系统管理,GC无法直接回收。所以要用到虚引用,当直接内存需要被回收的时候,通过引用队列进项检测,进而清理掉。C或C++虚拟机,采用delete或free。Java可以采用的是UnSafe类中的freeMemory()进行回收

3:ThreadLocal

3.1:线程本地

别的线程无法访问到

3.2:原理

set()源码:Set的时候设到了当前线程的map中,其他线程是读不到的
map不为空:Thrad.currentThread.map(ThreadLocal,valve)
Map等于空:初始化map

3.3:ThreadLocal与弱引用的配合使用,解决内存泄露

ThreadLocal的map中的entry是弱引用
多线程与高并发四:VarHandle与强软弱虚引用和ThreadLocal_第2张图片
1:解决的内存泄漏问题:若是强引用,即使tl=null,但key的引用依然指向ThreadLocal对象,ThreadLocal无法被回收,会有内存泄露。使用弱引用使得key指向ThreadLocal对象的引用变成可回收的.解决了内存泄漏问题.
2:存在的内存泄漏问题:ThreadLocal被回收了以后,key的值变成null,导致value无法被访问到,还存在内存泄露问题。所以,一般Threadlocal用完了,手工remove掉。

注意:本文仅代表菜鸟博主的个人观点,如果哪里不对或者路过技术大大有更好的想法,欢迎留言告知,分享和交流使我们进步,谢谢。

你可能感兴趣的:(多线程与高并发)