java中的锁---volatile(这玩意儿不叫锁,只是和锁有关)

参考:
https://www.cnblogs.com/dolphin0520/p/3920373.html
https://www.jianshu.com/p/157279e6efdb
https://blog.csdn.net/ThinkWon/article/details/102243670
https://www.jianshu.com/p/3893fb35240f
https://zhuanlan.zhihu.com/p/138819184
https://cloud.tencent.com/developer/information/volatile%E5%85%B3%E9%94%AE%E5%AD%97%E8%AF%A6%E8%A7%A3
https://www.jb51.net/article/197078.htm
https://www.yisu.com/zixun/197907.html
https://www.zhihu.com/question/329746124

含义:
volatile是并发编程中的一个关键字,只能修饰变量,无法修饰方法及代码块等,
多线程访问volatile不会发生阻塞,效率比synchronized高,而synchronized会出现阻塞。
volatile能保证数据的可见性,但不能保证原子性

volatile 作用:
1- 保证变量的内存可见性(不保证原子性)
volatile 用于将变量标记为“存储于主内存中”。更确切地说,对 volatile 变量的每次读操作都会直接从计算机的主存中读取,
而不是从 cpu 缓存中读取;同样,每次对 volatile 变量的写操作都会直接写入到主存中,而不仅仅写入到 cpu 缓存里。当然代价也比较高
2- 禁止指令重排序
volatile关键字禁止指令重排序有两层意思:
1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;
2)在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

原理:
下面这段话摘自《深入理解Java虚拟机》:
  “观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
  lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
  1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
  2)它会强制将对缓存的修改操作立即写入主存;
  3)如果是写操作,它会导致其他CPU中对应的缓存行无效。

问题:
volatile和static的区别
volatile:声明变量的一致性(工作内存和主内存数值保持一致)
static:声明变量的唯一性(各个线程可能具有本地缓存的值)

i++是不是线程安全?为什么?Java有哪些办法让i++变成线程安全?
不是,i++的执行分为 读取.赋值.回写,没办法保证原子性,所以不是线程安全的
线程安全可以采用,synchronized加锁,Lock加锁,或者采用JUC包下的AtomicInteger

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值