003-线程安全分析

线程安全

是什么

多线程多次执行的情况下,程序不会出现问题

安全方案

线程封闭

  1. 栈封闭
  2. 线程本地变量

无状态的类

没有成员变量

不可变类

所有成员变量都有final关键字修饰
如果修饰对象 必须保证对象本身线程安全

加锁或者CAS

使用锁工具
使用synchronized
修改数据使用CAS机制

案例

java中的Date 就是线程不安全的
而1.8 新出的 LocalDate 就是线程安全的

如果方法中传入了Date类型的对象
那么如果被修改了Time 那么其他线程就会看到这个改变
这种改变也许是无意的、不是期望的
在这里插入图片描述
两次打印的结果是不一样的
在这里插入图片描述

而localDate没有提供任何修改成员变量的方法
因为所有成员变量都是final修饰的
在这里插入图片描述
就算有修改需求也是返回对象的拷贝
在这里插入图片描述
所以我们认为 LocalDateTime是线程安全的
当然再实际操作Date对象的时候推荐使用lang3包里的DateUtils

常见问题

死锁

条件同时满足才会出现死锁:

  1. 多个操作者 n1
  2. 多个资源 n2
  3. n1 >= n2
  4. 资源争抢无序
  5. 抢到后不释放资源

在这里插入图片描述

解决

破坏其中一个条件:

  1. 资源争抢无序
    1.1 代码调整
    1.2 锁资源排序
  2. 抢到后不释放资源
    2.1 持有资源有限时间
    2.1 判断是否持有资源成功 如果不成功则释放所有资源 后重试

活锁

在上边例子2.1中
如果两个线程2把锁 顺序不一致
虽然会释放锁 但是2个线程同时执行到拿第二个资源的时候还是无法拿到
会进入重试
总体会造成CPU 一直在运行 但是卡在获取锁的过程中

解决

拿锁时间错开随机时间

线程饥饿

线程一直拿不到锁

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值