001-线程间的通信、协作、隔离

本文介绍了Java中线程间通信的关键技术,包括synchronized用于保证同步,volatile确保变量可见性,以及等待/通知机制(wait(),notifyAll())实现线程协作。ThreadLocal提供线程局部变量,避免参数传递,其内部使用ThreadLocalMap并可能存在内存泄漏问题,因此使用后应适时remove()。
摘要由CSDN通过智能技术生成

线程间的通信和协作

synchronize

volatile

保证了不同线程对变量进行操作的可见性
如静态变量
不加关键字则子线程无法感知主线程变更
加了就能感知到主线程对静态变量的修改
使用场景:一个线程写,多个线程读

等待/通知机制

单纯的轮询耗费性能,单机情况下可以使用等待通知机制实现
wait() 和 notifyAll() 两个方法必须放在同步方法中或者同步块中
角色:

  • 等待方
  • 通知方

等待方:

sybchronized (对象) {
	while (条件不满足) {
		对象.wait();
		//此时释放锁,线程进入等待
	}
}

通知方:

sybchronized (对象) {
	业务处理;
	对象.notifyAll();
}

ThreadLocal

什么用

是什么:当前线程数据副本
什么用:跨方法参数传递

实现

ThreadLocalMap

考虑到性能问题 数据副本每个线程自己持有最快
每个线程初始化的时候 创建一个ThreadLocalMap
Map中的每个Entry 的key 是 ThreadLocal, value是存入的值

下图是一个将ThreadLocal声明为静态变量的内存对象模型图
实线箭头是:强引用
虚线箭头是:弱引用
在这里插入图片描述

属于这个线程的ThreadLocal值。这个映射由ThreadLocal类维护。
在这里插入图片描述
ThreadLocal中set()的时候 获取map 如果没有则创建
在这里插入图片描述
在这里插入图片描述
首次懒加载Map
在这里插入图片描述

数据副本

这里的数据副本不是说会对对象进行复制还是什么其他操作
这里的副本就是 set(Object value) 的value 本身
所以在使用 ThreadLocal 的时候 内容需要在线程中自己创建 或者在 initialValue()中创建
如果设置一个公共的变量 那么隔离机制会被打破

Hash冲突

开发地址法:线性探测
如果存储的时候hash位置被占用 则依次往下找空位

从计算出来的hash 作为索引i开始 如果table[i]内容 e 不为空
则 判断:
如果 e 等于 传入的ThreadLocal 则 替换值
如果 e 为 null 则重新刷新 Entry *(1)
当For循环 执行完还没有跳出的话 i 的值就是 第一个空的位置
直接塞进 table即可
在这里插入图片描述
这里就是简单的判断如果 i小于长度 -1 则返回 i+1 否则就是到尾部了 直接从 0 开始
在这里插入图片描述
(1) 为什么有Entry不为空 其中的key为空呢?
因为key 用的软引用,下边内存泄漏有解释

(2) 那会不会出现所有槽位都已经插满了内容而无法处理hash冲突了
默认的容量是16
每次插入内容会判断一下是否 size已经大于容量的3/4了
如果大于则 容量 * 2扩容
在这里插入图片描述

内存泄漏

局部变量的生命周期应该是同方法一致
但是ThreadLocal是绑定在线程上的
存放的局部变量生命周期可能和线程一致
而线程池中的线程长期存活
就会造成内存泄漏

本质是
就算方法执行完毕 ThreadLocal对象因为局部变量的出栈
也就entry的key无用了 再GC时候会直接清理(弱引用)
但是entry 的 value 还在引用 但是无法访问了

引用链:Thead -> ThradLocalMap -> Entry[] -> entry -> value

所以:ThreadLocal 必须 remove()

为什么使用弱引用

如果不用弱引用
则用户没有手动remove() 的情况下 Entry中的key 也会产生内存泄漏

为什么使用弱引用再GC的时候没有问题

一般我们使用ThreadLocal创建静态变量直接new出来
虽然ThreadLocalMap中对ThreadLocal引用是弱引用
但是直接new出来的部分是强引用
保证ThreadLocal不会被清除
在这里插入图片描述
就算是成员变量
在方法还未出栈的时候ThreadLocal由对象强引用
所以仍不会被销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值