关于volatile与System.out的“冲突”导致的内存屏障失效问题

2024-06-16 18:52

本文主要是介绍关于volatile与System.out的“冲突”导致的内存屏障失效问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

起因:今天在写一个volatile相关的Demo,本来想的是一个线程根据这个IS_STOP去一直进行循环,直到另一个线程改变为true就中断。内存屏障的问题会导致虽然其他线程修改了值,但是原线程是不知道的,会继续循环,所以必须加volatile关键字来让其可见。按道理是这样的,但是突然发现把volatile删了也是正常停止了,愣了直接,难道不加也能可见?代码和结果如下:

import java.util.concurrent.TimeUnit;
/*** 定义一个静态变量,一个线程在执行时,如果该变量被其他线程置为true,就中断该线程*/
public class VolatileDemo {
//    public static volatile boolean IS_STOP = false;static boolean IS_STOP = false;public static void main(String[] args) {Thread t1 = new Thread(()->{while (true){System.out.println("正在执行");if(IS_STOP){System.out.println("停止执行");break;}}},"t1");t1.start();try{TimeUnit.SECONDS.sleep(1);}catch(Exception e){e.printStackTrace();}Thread t2 = new Thread(()->{IS_STOP = true;//将该变量设置为true},"t2");t2.start();}
}

在这里插入图片描述

经过:通过上面的图可以看到明明没有volatile关键字,但是t2修改那个值为true之后t1的循环还是正常停止了,JVM也正常退出,难道是之前学的不对?疑惑中我将所有的打印注释掉也试了试,竟然发现线程t1的循环又没有被中断了,jvm没有退出,如下图所示,这表示内存屏障确实存在:

在这里插入图片描述

再用java自带的线程可视化界面查看下线程信息,确实还在正常运行:

在这里插入图片描述

调查:那就肯定是System.out这块出问题了,猜想肯定是里面有啥处理把线程的工作区刷新了,导致虽然我没有写volatile,但是已经刷新值了,随即进入println的代码中进行查看,发现果然调用println()时里面使用了synchronized关键字,如图:

在这里插入图片描述

结论:没有volatile确实是会有内存屏障存在,但是如果其中使用的某些法方法里面使用了synchronized关键字,那么就会导致出现“好像不加volatile也行”的错觉。线程进行加锁时势必会先进行线程工作区的重置,从主存下载最新的值才能开始进行操作,解锁时也必须要把最新的值再次写回主存。就像一个项目现在交给你来干了,第一步肯定要先保证自己本地代码是最新的一样。

这篇关于关于volatile与System.out的“冲突”导致的内存屏障失效问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067271

相关文章

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对