Java中的volatile关键字的作用

volatile的用法

volatile首先只能用于类的成员变量,因为volatile的作用是保证多线程之间对变量的可见性。所以如果使用volatile关键字修饰局部变量,由于每一个线程都有自己的私有的栈空间,所以局部变量无法被其他的线程所访问。不volatile只能用于修饰类的成员变量。

代码案例(内存可见性)

java 复制代码
package org.example.thread;
import java.util.Scanner;
public class volatileDemo {
    public static int isQit = 2;
    public static void main(String[] args) {

        Thread t = new Thread(()->{
            while(isQit!=0){

            }
            System.out.println("finished");
        });
        Thread t2 = new Thread(()->{
            Scanner scanner = new Scanner(System.in);
            System.out.println("please enter a number: ");
           isQuit = scanner.nextInt();
        });
        t.start();
        t2.start();

    }
}

线程t死循环判断isQuit的值,但是while循环里什么也不做。线程t2用于修改isQuit的值,以达到终止线程t的循环的功能。但是执行后发现输入的值是0也无法终止线程t的循环。

但是在isQuit前面加上volatile关键字即可完成该功能。

内存可见性分析

为何加了volatile关键字就可以了呢??

因为线程t在判断时,编译器可能为了提高读取效率,本来isQuit变量应该被存储在内存中,等待编译器去读取,但是编译器为了提高读取效率,就会将isQuit的值直接读取到寄存器中。故每次进行循环时,读取的都是寄存器中的值,但是线程t2修改的isQuir变量的结果是直接写入到内存中,故线程t并没有感知到,所以一直进行死循环。

代码案例(指令重排序)

见文章:https://blog.csdn.net/weixin_73906153/article/details/156691700?spm=1001.2014.3001.5501 末尾

使用建议

只要是在同步代码块中需要被修改获取的成员变量,都尽量使用volatile关键字进行修饰,防止出现意料之外的问题。

相关推荐
圆山猫2 小时前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
微学AI3 小时前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
城管不管3 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
IT小白杨3 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
豆瓣鸡4 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖4 小时前
Java深入解析篇九之NIO详解
java·网络·nio
韭菜炒鸡肝天4 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
The Chosen One9854 小时前
高进度算法模板速记(待完善)
java·前端·算法
Aaron - Wistron5 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
Dxy12393102166 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python