volatile关键字

Java内存模型

在 JDK1.2 之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。

而在当前的 Java 内存模型下,线程可以把变量保存本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。

  • Java所有变量都存储在主内存中
  • 每个线程都有自己独立的工作内存,里面保存该线程的使用到的变量副本(该副本就是主内存中该变量的一份拷贝)

在这里插入图片描述

  • 线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接在主内存中读写
  • 不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。
  • 线程1对共享变量的修改,要想被线程2及时看到,必须经过如下2个过程:
    (1)把工作内存1中更新过的共享变量刷新到主内存中
    (2)将主内存中最新的共享变量的值更新到工作内存2中

这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。
在这里插入图片描述
要解决这个问题,就需要把变量声明为volatile,这就指示 JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。

volatile 关键字的主要作用就是保证变量的可见性然后还有一个作用是防止指令重排序
在这里插入图片描述

synchronized 关键字和 volatile 关键字的区别

  • Synchronized保证内存可见性和操作的原子性;Volatile只能保证内存可见性
  • Volatile不需要加锁,比Synchronized更轻量级,并不会阻塞线程(volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。)
  • volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化(如编译器重排序的优化).
  • volatile是变量修饰符,仅能用于变量,而synchronized是一个方法或块的修饰符。
  • volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性
  • volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些

可见性:一个线程对共享变量的修改,能够及时的被其他线程看到 。
原子性:即不可再分,不能分为多步操作。比如赋值或者return。比如”a =1;”和 “return a;”这样的操作都具有原子性。类似”a += b”这样的操作不具有原子性,在某些JVM中”a += b”可能要经过这样三个步骤:① 取出a和b ② 计算a+b ③ 将计算结果写入内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值