volatile详解

1. Wait set(wait队列)

  1. 名称解析:当对于同一个锁而言,会把所有的wait线程,加入到自己的一个wait set中。
  2. 注意点:
    1. 所有对象都会有一个wait set,用于存放调用了该对象的wait方法之后进入block状态的线程。
    2. 线程被notify之后,不一定立即执行,需要再次去抢锁,才能获得CPU执行权。
    3. 线程从wait set中被唤醒的顺序不一定是FIFO。
    4. 线程被唤醒后,必须重新获取锁。 然后,跳转到wait之后的代码接着执行。

2. JMM

在这里插入图片描述

1. 缓存一致性:
  1. 概念
    1. 每个CPU都会使用cache一部分数据。
    2. java会对于只有读操作的线程,只在线程启动时去主存获取数据;而对于有写操作的线程则会去内存中多次获取数据以及更新数据
    3. 因此会导致数据的不一致。
  2. 解决方法:
    1. 给数据总线加锁;总线分为(数据总线、控制总线、地址总线);硬件之间的通信是通过总线来传递数据的,因此,CPU与内存之间也是通过总线通信。所以,Lock住总线,就保证修改数据的唯一性(在同一时刻,只有一个线程能够修改数据)。
    2. CPU高速缓存一致性协议(MESI)。 保证多线程之间获取到的数据是准确的,是互相可见的。
  3. 核心思想:
    1. 当CPU写入数据的时候,如果发现该变量被共享(也就是在其它CPU中存在该变量的副本),会发出一个信号,通知其它CPU该变量缓存无效。
    2. 当其它其它CPU访问该变量的时候,重新到主内存中获取数据。
2. 重排序:

保证最终一致性,而且,变量之间如果有依赖关系,则不能重排序,无关的变量可能会发生重排序。

3. java线程安全三原则
  1. 原子性:

    1. 定义: java规范中,规定对于基本数据类型的变量读取和赋值是原子性的,要么都成功,要么都失败,这些操作不可被打断。 但对于long和double需要注意CPU位数,若在32位的机器上也可能不是原子性的,因为long和double是64位的;可能会把高32位和低32位分开存储。
    2. 事例:
      1. a=10; 原子性,只是一个读取操作。
      2. b=a; 不满足,1. 读取a; 2. 把a赋值给b。
      3. c++; 不满足,1. 读取c;2. c+1;3. 把值赋给c;
      4. c=c+1;和3一致。
  2. 可见性:

    1. 定义:在java中,使用Volatile关键字修饰的变量;当此变量发生改变,所有CPU缓存中的此变量失效,都得到主内存中去获取最新的变量;但是,Volatile关键字无法保证原子性。
  3. 有序性:

    1. 定义:最关键的是,需要保证最终一致性原则。
    2. 规则:
      1. 代码的执行顺序:编写在前面的,发生在编写后面的; eg: b=a+1; 操作的时候是先a+1;再是赋值给b;
      2. unlock必须发生在lock之后。
      3. Volatile修饰的变量,对于一个变量的写操作先于对改变量的读操作。
      4. 传递规则:操作A优先于B,B优先于C,那么A肯定优先于C;

3. volatile

1. 语义
  1. 一旦使用Volatile修饰某个变量的时候,此变量就具备了两次语义。
    1. 保证了不同线程之间的可见性
    2. 禁止对其进行重排序,也就是保证了有序性
    3. 并未保证原子性。
2. 使用场景
  1. 状态量。必须使用volatile关键字;
    在这里插入图片描述
  2. 因为保证代码的有序性;保证Volatile变量任何使用地方之前的代码是执行完了的,之后的代码得等Volatile变量执行完,才能执行。
3. 底层原理
  1. 只有在多核处理器上,才会对总线加Lock前缀;在单核CPU上不需要LOCK;
  2. Intel在早起是在总线上增加Lock前缀;后期改为使用缓存锁来保证指令执行的原子性。提高了Lock前缀指令的执行开销。
4. final域的内存语义
  1. 读写禁止重排序;
  2. 保证了初始化安全;
  3. 只要对象时正确构造的,那么不需要使用同步来保证任意线程都能看到这个final域在构造函数中被初始化之后的数据;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值