Java内存模型JMM

1.JMM介绍:

Java内存模型规定了所有的变量都存储在主内存(Main Memory)中,每条线程还有自己的工作内存(Working Memory)
线程的工作内存中保存了被该线程使用的变量的主内存副本线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的数据。
不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
下图描述了线程、主内存、工作内存三者的交互关系:

package com.fll.jvm;

public class JMM_Test01 {

	public static void main(String[] args) {

		Number n = new Number();
		
		//开启A线程
		new Thread(()->{
			System.out.println(Thread.currentThread().getName()+"开始修改:  "+n.number);
			
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			n.addTo1000(); //将number修改成1000
			System.out.println(Thread.currentThread().getName()+"已经修改好了: "+n.number);
		},"线程A") .start();
		
		//main线程
		while(n.number == 10) {
			//需要有一种通知机制告诉main线程,number被修改了
		}
		
		System.out.println(Thread.currentThread().getName()+":number: "+n.number);
	}
}

class Number{
	
	int number = 10;
	//加上volatile之后可以增加可见性
//	volatile int number = 10;
	
	public void addTo1000() {
		this.number = 1000;
	}
}

执行的输出如下图:

现象:main线程一直在等待,说明main线程中的变量没有被修改。直接说明A线程修改了工作内存中的number 并上传至主内存,但是main线程也有一份之前一样的工作副本,如果不通知main线程,那么main线程将一直等下去。
但是如果将number 用volatile修饰,程序会立马结束。

volatile解析

volatile关键字是Java虚拟机提供的最轻量级同步机制
具备以下两个特性:

  1. volatile修饰的变量在多线程中保证了可见性
  2. volatile修饰的变量能禁止指令重排序优化
    但是并不能保证原子性...
posted @ 2021-02-26 10:54  方罗良  阅读(65)  评论(0)    收藏  举报