线程安全问题

可见性(volatile)

在线程中,存在 主内存 和每个线程各自的 工作内存 ,线程运行时会把主内存中的拷贝过来并进行操作。

如果不加volatile关键字的话,在一个线程中修改后,其他线程是不可见的。

加了volatile关键字后,在一个线程中修改时会将主内存中的同时进行刷新,其他线程就可看见修改后的内容。

例:
在这里插入图片描述
在这里插入图片描述
可以看到给flag加了volatile关键字后,b线程将其修改后对a线程是可见的

原子性(Atomic)

指一个操作是不可中断的。操作要么全部执行,且执行过程中不被打断,要么不执行。
例:
虽然使用了volatile关键字使 x 为可见的,但是
由于x++是非原子性的,所以程序运行结果错误
在这里插入图片描述
需要使用AtomicInteger来保证 x 的原子性
在这里插入图片描述
AtomicInteger是利用循环CAS实现原子性的

CAS

Compare And Swap
在改变值之前先比较值是否与改之前的值相同,如果相同,则将其改变。如果不同,说明值已经被其他线程改过,则不进行操作。

CAS会产生

  1. ABA问题:一个值A变成B以后又被改回到A(即 值 被别的线程动过)

解决ABA问题:加一个版本号

对值进行操作时需要同时满足两个条件:
(1)值相同
(2)版本号相同

  1. 时间开销大
    CAS如果长时间不成功,会给CPU带来非常大的执行开销

  2. 只能保证一个共享变量的原子操作

JAVA线程原子类

1.基本数据类型

AtomicBoolean
AtomicInteger
AtomicLong

2.数组

AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray

3.引用

AtomicReference
AtomicReferenceFiledUpdater
AtomicMarkableReference

4.字段

AtomicIntegerFiledUpdater
AtomicLongFiledUpdater
AtomicStampedReference

有序性(volatile)

程序执行的顺序按照代码的先后顺序执行。

在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

可以使用 volatile 关键字来保证有序性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值