多线程之线程安全

一、线程安全

什么是线程安全

如果多线程环境下代码运行的结果是符合预期的,则说这个程序是安全的

线程不安全的原因

  1. 线程调度的随机性
  2. 修改共享数据
    即多个线程针对某一个共享变量进行修改.
  3. 原子性
    指令不可分割
  4. 内存可见性
    在多线程中,某一线程对数据的操作,其他线程能否及时看见
  5. 指令重排序
    指Jvm,编译器会对代码进行优化,可能会改变代码的执行顺序

二、解决方法

1.Synchronized关键字

a.实现原理

基于操作系统的mutex互斥锁

b.特点
  • 互斥性
    通过加锁,当多个线程同时竞争同一资源时,同一时间内只有一个线程会拿到这把锁,而未抢上锁的线程会进行阻塞等待,直到该线程释放锁后,由操作系统唤醒阻塞线程中的某一个.通过互斥达到原子性

  • 内存可见性
    当一个线程进行加锁后,会从主内存拷贝变量的副本到工作内存,代码执行完后,再将工作内存的值更新到主内存,然后释放锁

  • 指令重排序
    synchronized 对指令重排序有一定约束作用,但并不能完全禁止

2.Volatile关键字

a.实现原理

通过插入内存屏障,强制对缓存的修改操作即刻写入主存;确保指令重排序时不会把其后面的指令排到内存屏障之前,也不会把前面的指令排到内存屏障后

b.特点
  • 不保证原子性
  • 内存可见性(强制)
    Volatile修饰的变量,读取变量时,会从主内存中读取该变量的最新值到工作内存,再从工作内存中读取副本; 写入变量时,先改变变量副本的值,然后再强制将改变后副本的值从工作内存刷新到主内存。
  • 禁止指令重排序
    被volatile修饰的变量,编译器不会再进行优化

三.总结

区别SynchronizedVolatile
原子性可以保证不能保证
内存可见性可以保证可以保证
指令重排序有一定约束禁止
修饰方法和代码块变量
是否引发线程阻塞不会
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值