一、并发和并行的区别
并发 多个线程同时访问同一个资源
并行 各种事情一路并行做
二、谈谈你对volatile的理解
1、volatile是java虚拟机提供的轻量级同步机制 保证可见性,不保证原子性,禁止指令重排序。
2、JMM
2.1什么是线程可见性?
证明
2.2什么是原子性?
不可分割,完整性。某个线程在做某个业务的时候,中间不可以被加塞或分割。需要整体完整。
要么同时成功,要么同时失败。
为什么volatile不保证原子性?
多线程情况下,会出现写覆盖,丢失数据现象。虽然加了volatile,但是来不及通知其他线程,就写入了主内存中。
如何保证原子性??
①加sync
②使用juc下的atomicInteger
有序性?
volatile禁止指令重排序
例子 做试卷先做会的,再做不会的。
指令重排 ---》 编译器优化,指令并行,内存系统重排序
int a,b,x,y =0;
线程1 线程2
x = a; y=b;
b =1; a=2;
x= 0; y=0;
指令重排后
b =1; a=2;
x = a; y=b;
x=2;y=1 数据错误,无法保证一致性
线程安全保证
对于工作内存和主内存存在延时可见的问题
可以使用sychronized或者volatile,都可以使线程修改后立即对其他线程可见。
对于指令重排导致的可见性问题和有序性问题。
可以利用volatile来禁止指令重排序
volatile的使用场景
单例模式
DCL 创建对象的时候, 1.分配内存空间 2.初始化对象 3. 设置值指向对象地址 123均不存在数据依赖关系,所以有可能发生指令重排。导致线程获取到了半初始化的对象。