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 @   方罗良  阅读(58)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示