Java并发编程学习记录(二)- Volatile

一、Volatile

  1. 可见性: 使用volatile修饰的对象,对其他线程可见。当线程A修改对象t后,会将t写回主内存,因为缓存一致性原则,当线程B修改t时,会从主内存中读取最新的t。
  2. 禁止指令重排序。实现过程:
    a. java层面添加volatile关键词。
    b. 编译为java字节码后,对象前会添加修饰符ACC_VOLATILE。
    c. 在jvm层面,会在指令前后增加内存屏障,禁止指令重排。根据JSR规范,内存屏障分类: LoadLoad,StoreStore,LoadStore,StoreLoad。
    d. 在汇编层面是通过Lock指令锁总线来实现的。

二、强软弱虚引用

  1. 强引用: 正常的引用,没有任何引用指向的对象会被垃圾回收器回收。
  2. 软引用: 当内存不够时,软引用会被回收,经常用作缓存。
  3. 弱引用: 只要只有弱引用指向的对象,垃圾回收时就会被回收,应用场景: ThreadLocal。
  4. 虚引用: 堆外内存管理,比如 zerocopy; 直接内存管理,比如nio。

三、ThreadLocal

1. 概念

ThreadLocal 叫做本地线程变量,意思是说,ThreadLocal 中填充的的是当前线程的变量,该变量对其他线程而言是封闭且隔离的。

2. 源码实现

在Thread类中,有一个ThreadLocalMap的成员变量 threadLocals,ThreadLocal对象 tl 执行set方法时,会从当前线程中获取threadLocals变量,然后以当前ThreadLocal为key,保存进ThreadLocalMap中的Entry数组中,而Entry继承了WeakReference<ThreadLocal<?>>(弱引用), 因此指向ThreadLocal对象的有两条引用,一条tl强引用,一条ThreadLocalMap中key指向的弱引用,这样当tl为null时,垃圾回收时可以直接回收ThreadLocal。

3. ThreadLocal的内存泄漏

当强引用tl为null时,ThreadLocal会被回收,导致ThreadLocalMap中key值为null,value值再也无法被获取到,这部分空间无法被回收。

解决方法: 当确认ThreadLocal不再被使用时,执行remove()方法,将ThreadLocalMap中的key和value清除,释放空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值