线程安全如何理解

所谓线程安全,简单来说就是在多线程环境下,多个线程去访问同一个资源得到的结果都是一致的,正确的;

线程安全问题的具体表现在三个方面,原子性、有序性、可见性。

原子性呢,是指当一个线程执行一系列程序指令操作的时候,它应该是不可中断的,因为一旦出现中断,
站在多线程的视角来看,这一系列的程序指令会出现前后执行结果不一致的问题。
这个和数据库里面的原子性是一样的,就是一段程序只能由一个线程完整地执行完成,而不能存在多个
线程干扰

CPU 的上下文切换,是导致原子性问题的核心,而 JVM 里面提供了 Synchronized 关键字来
解决原子性问题。


可见性呢, 就是说在多线程环境下,由于读和写是发生在不同的线程里面,有可能出现某个线程对共享变
量的修改,对其他线程不是实时可见的。
导致可见性问题的原因有很多,比如 CPU 的高速缓存,L1,L2缓存是CPU私有的,并且CPU会优先从这个 CPU cache中读取数据,在数据没有持久化到内存时,就容易出现数据不一致
比如一个变量 A=10, CPU 1号执行了 A+10,此时CPU 1号中的 A是20,但CPU为了性能考虑,通常是不会使用写直达这种,同时写缓存和内存的方式,而是选择写回这种标记脏页的方式.
若CPU 1号的 A=20没有写入内存的话,
且CPU 2号也去获取变量A,也执行了 A+10,那么CPU 2号的 A也是20.但实际上我们的计算机对 变量A执行了2次 A+10的操作,理应当答案为 A=30;

通常可以使用volatile关键字强行让CPU将数据写入主存中,而不是只写入自己的缓存,
也就是当一个线程修改了 volatile 变量的值后,其他线程能够立即看到最新的值。
因此可以解决可见性问题


有序性,指的是程序编写的指令顺序和最终 CPU 运行的指令顺序可能出现不一致的现象,这种现象也
可以称为指令重排序.

同样可以使用volatile解决有序性问题,因为volatile会禁止处理器对其进行重排序优化
即使编译器和处理器在进行指令重排时也会考虑 volatile 变量的内存屏障,从而确保变量的读写操作按照程序的顺序执行。
因此可以解决有序性问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值