1. volatile是java虚拟机提供的轻量级的同步机制
- 保证可见性
- 不保证原子性
- 禁止指令重排
2. JMM(java内存模型)你谈谈?
JMM(Java内存模型)本身是一种抽象的概念并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。
JMM关于同步的规定:
- 线程解锁前,必须把共享变量的值刷新回主内存。
- 线程加锁前,必须读取内存的最新值到自己的工作内存。
- 加锁解锁必须是同一把锁。
2.1 可见性
2.2 原子性
不可分割,完整性,也即某个线程正在做某个具体业务时,中间不可以被加塞或者被分割。 需要整体完整,要么同时成功,要么同时失败。
如何解决原子性?
- 加synchronized
-
2.3 volatile代码演示可见性
```java public class VolatileDemo { public static void main(String[] args) {
volatileVisibilityDemo();
atomicDemo();
}
private static void atomicDemo() {
System.out.println("原子性测试");
MyData myData=new MyData();
for (int i = 1; i <= 20; i++) {
new Thread(()->{
for (int j = 0; j <1000 ; j++) {
myData.addPlusPlus();
myData.addAtomic();
}
},String.valueOf(i)).start();
}
while (Thread.activeCount()>2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+"\t int type finally number value: "+myData.number);
System.out.println(Thread.currentThread().getName()+"\t AtomicInteger type finally number value: "+myData.atomicInteger);
}
//volatile可以保证可见性,及时通知其它线程主物理内存的值已被修改 private static void volatileVisibilityDemo() {
System.out.println("可见性测试");
MyData myData=new MyData();//资源类
//启动一个线程操作共享数据
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t come in");
try {
TimeUnit.SECONDS.sleep(3);
myData.setTo60();
System.out.println(Thread.currentThread().getName()+"\t update number value: "+myData.number);
}catch (InterruptedException e)
{
e.printStackTrace();
}
},"AAA").start();
while (myData.number==0){
//main线程持有共享数据的拷贝,一直为0
}
System.out.println(Thread.currentThread().getName()+"\t mission is over. main get number value: "+myData.number);
} }
class MyData{ int number=0; //volatile int number=0;
AtomicInteger atomicInteger=new AtomicInteger();
public void setTo60(){
this.number=60;
}
//此时number前面已经加了volatile,但是不保证原子性
public void addPlusPlus(){
number++;
}
public void addAtomic(){
atomicInteger.getAndIncrement();
}
2.4 有序性(了解)
3. 你在哪些地方使用过volatile?
单例模式DCL代码