什么叫做并发编程:
- 使用多线程充分利用cpu资源提高程序效率
- 解决多线程带来的线程安全问题
·线程内部数据其他线程不可见
·多线程打破了代码块的执行原子性(要么同时执行成功,要么同时执行失败)
·打破程序执行从上往下执行顺序(上一个线程可能已经在执行下面的代码了,另外一个线程才开始执行上面代码)
补充:一行代码并不代表着原子操作,只有一个汇编指令才是原子操作,所有非原子操作在多线程执行时都会出现线程不安全问题。
并发的3个基本概念(为了解决线程不安全问题,要保证三个基本操作)
- 原子性:
一个操作要么执行成功,要么执行失败
- 可见性
一个线程对共享数据的操作另外一个线程能立刻知道
- 有序性
即是按着代码执行的先后顺序执行。
从java的内存模型中可以看到,本线程内是有序的,从一个线程内看另外一个线程所有操作都是无序的。
Java 内存模型中允许编辑器和处理器对指令进行重新编排,但是不能影响最终的结果,这样单线程不会出现问题,但是多线程就不行。
多线程操作共享变量的方式:
逻辑方式
物理方式
这只是一个抽象模型,具体实现看对应的虚拟机。
为了解决多线程带来的线程不安全问题,java提供了锁和并发关键字来。
1.锁
锁采用互斥和可见性解决问题,互斥性就保证了代码块的原子性和有序性
2.并发关键字
一、Valotile作用
1.保证可见性
当写一个volatile 变量时,JMM 会把该线程本地内存中的变量强制刷新到主内存中
这个写操作会导致其他线程中volatile 变量缓存无效。
2.禁止指令重排
即执行到volatile 变量时,其前面的所有语句都执行,后面所有语句都未执行,且前面语句结果对volatile 变量及其后面语句可见。
Valotile的优缺点: 优点可以使共享变量同步,轻量级的同步操作,不会发生线程阻塞,而导致占用了大量的cpu资源。缺点是不保证原子性,所以只能用于本身就是原子操作的指令
像i++ 就不是原子操作不可以使用。
二、Valotile原理
- 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面,即在执行到内存屏障这句指令时,在它前面的操作已经全部完成
- 它会强制将缓存的修改操作立即写入主存
- 如果是写操作,它会导致其他CPU中对应的缓存行无效。
引用:
Java volatile关键字最全总结:原理剖析与实例讲解(简单易懂)_夏日清风-CSDN博客_java volatile