您当前的位置: 首页 >  Java

java持续实践

暂无认证

  • 3浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java多线程 volatile 作用与总结以及与synchronized关系

java持续实践 发布时间:2020-09-06 15:04:28 ,浏览量:3

文章目录
      • volatile的两点作用
      • volatile与synchronized 的关系
      • volatile总结

volatile的两点作用
  1. 保证可见性: 读取一个volatile 变量之前, 需要先使相应的本地缓存失效. 这样就必须到主内存读取最新的值,把读取到的最新的值, 放到子线程的工作内存中去. 写一个volatile 修饰的属性, 会立即刷入到主内存.
  2. 禁止指令重排: 解决单例双重锁乱序问题. 关于指令重排序,之前写的如下这篇文章中有提到指令重排序问题. https://javaweixin6.blog.csdn.net/article/details/108417366 只有发生了重排序, 才会出现x= 0 , y=0的情况. 把上面文章中的代码, 修改如下, 变量加上volatile修饰, 那么就不会出现重排序问题了. 也就是说不会出现上面文章中x和y都是打印0的情况了. 运行如下, 没有出现打印出x和y为0的情况
volatile与synchronized 的关系

volatile可以看做是轻量级的synchronized . 如果一个共享变量, 一直只被各个线程赋值, 而没有其他的操作, 那么就可以用volatile来代替synchronized 或者代替原子变量, 因为对布尔变量的赋值自身是有原子性的, 而volatile保证了可见性, 就满足了线程安全. 因为布尔值, 只是改成true或者false, 具有原子性, 而不是像 a++操作是非原子性的.

volatile总结
  1. volatile的使用场景有限. 一个共享变量, 一直只被各个线程赋值, 而没有其他的操作, 那么就可以用volatile来代替synchronized 或者代替原子变量. 或者是用作触发器
  2. volatile 的属性和读写操作都是无锁的 ,不能替代synchronized , 因为volatile 没有提供原子性和互斥性. 但同时, 由于volatile 无锁, 不需要花费时间在获取锁和释放锁上, 因此是轻量级的.
  3. volatile 只能用作于属性上, 不像synchronized 是可以用在方法或者代码块上. 用volatile 修饰的属性, 编译器不会进行指令重排.
  4. volatile 提供了可见性, 任何一个线程对其的修改, 将立即对其他线程可见. volatile 修饰的属性不会被线程的工作内存缓存, 始终从主存中读取.
  5. volatile 提供了happens-before保证, 对volatile修饰的变量a一旦写入, 那么后续的操作一定是读取的最新的值.
  6. volatile 可以使得long 和double类型的赋值保证其原子性.
关注
打赏
1658054974
查看更多评论
立即登录/注册

微信扫码登录

0.0366s