Java——》可见性

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Redis】
    总结——》【Kafka】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】
    总结——》【Linux】
    总结——》【MongoDB】
    总结——》【Elasticsearch】

Java——》可见性

  • 一、概念
    • 1、可见性问题
    • 2、为什么会有可见性问题
    • 3、数据同步过程
  • 二、在Java中保证可见性的方式
    • 1、volatile
    • 2、synchronized
    • 3、Lock锁
    • 4、final

一、概念

可见性是指线程间的,对变量的变化是否可见。通常被解释为将线程本地状态反映到主内存上,volatile就是负责保证可见性的。

1、可见性问题

可见性问题是指一个线程修改了一个共享变量的值,但是另一个线程无法立即看到这个修改后的值。

2、为什么会有可见性问题

CPU处理速度非常快,相对CPU来说,去主内存获取数据这个事情太慢了,CPU就提供了L1,L2,L3的三级缓存,每次去主内存拿完数据后,就会存储到CPU的三级缓存,每次去三级缓存拿数据,效率肯定会提升。

因为每个线程都有自己的工作内存(CPU三级缓存),线程之间无法直接访问对方的工作内存,只改自己的工作内存,没有及时的同步到主内存,导致一个线程对共享变量的修改对其他线程不可见,从而出现数据不一致。

3、数据同步过程

CPU在处理时,需要将主内存数据刷新到寄存器中再执行指令,执行完指令后,再将寄存器数据刷新到主内存中。遵循MESI协议,不是每次操作结束都将CPU缓存数据同步到主内存。
Java——》可见性_第1张图片

二、在Java中保证可见性的方式

1、volatile

参考链接:Java——》volatile

保证每次CPU操作数据时,修改后的值立即被写回主内存,其他线程在读取该变量时可以直接从主内存中获取最新值

2、synchronized

参考链接:Java——》synchronized保证可见性

确保同一时刻只有一个线程访问共享变量,从而避免了多线程并发访问时对共享变量的竞争和冲突

3、Lock锁

参考链接:Java——》ReentrantLock

Java——》可见性_第2张图片

4、final

final修饰的属性,在运行期间是不允许修改的,这样一来,就间接的保证了可见性,所有多线程读取final属性,值肯定是一样。

Q:final和volatile不允许同时修饰一个属性?
A:final修饰的内容已经不允许再次被写了,而volatile是保证每次读写数据去主内存读取,并且volatile会影响一定的性能,就不需要同时修饰。
image.png

你可能感兴趣的:(Java,java,可见性,volatile,synchronized,Lock,final)