并发编程中数据的可见性

一、什么是并发编程的可见性?

  在并发编程中,“可见性”是指一个线程对共享变量的修改是否能被其他线程及时看到的特性。

二、不可见情况的测试

    现在设置成员属性flag=true,如果flag=true则t1线程一直死循环执行任务,main线程设置flag=false,那么t1线程按道理应该结束任务,代码如下:

public class NoVisibleTest {

    private static volatile boolean flag = true;
    
    public static void main(String[] args) throws InterruptedException {

        new Thread(() -> {
            while (flag) {
                //  死循环执行任务
            }
            System.out.println("t1线程任务执行结束");
        }, "t1").start();

        //  主线程休眠1s,等待t1进入循环
        Thread.sleep(1000);

        //  修改flag为false
        flag = false;
        System.out.println("main线程执行结束");
    }
}

  可执行结果是 main线程执行结束,t1线程仍在一直死循环执行。要想搞清楚其中的原理就要理解底层。

三、计算机硬件简单分布结构

    每一个CPU都会有自己的三级缓存(L1、L2、L3),并且自己CPU的三级缓存不能被其他CPU访问,内存的访问速度相对于CPU实际上是很慢的,让CPU直接访问内存效率很低,所以加入三级缓存提高CPU的执行效率

    但是CPU执行修改操作时只是将三级缓存给修改了,并没有修改内存,这就导致虽然main中的flag=false,但是t1线程并不知道

四、解决方案

  解决方案一:

    在flag属性前加上volatile关键字修饰,

private static volatile boolean flag = true;

    作用是令三级缓存中的flag属性失效,这样每次访问flag都要从内存重新读取,每次修改都会立刻同步到内存

  解决方案二:

    在while循环内部加上synchronized,如:

 while (flag) {
     synchronized(NoVisibleTest.class) {
         
     }
 }

​     原理是synchronized每次抢到锁、释放锁,都会将三级缓存与主存进行同步,这就保证了数据的可见性

其他解决方案:

​     在while循环内部使用System.out.println()语句,因为内部使用了synchronized;

​     使用AtomicInteger类,内部使用了volatile关键字

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938115.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不配置python环境,直接用PyCharm就可以?

有的伙伴可能遇到不安装python环境只安装pycharm也可以进行运行代码。 所以自认为是不需要解释器就可以运行? 这个是不现实的,有很多伙伴可能是安装了Pycharm,但Pycharm看你电脑上没有解释器,所以在安装的时候给你默认安装在C盘…

C语音顺序表专题及应用

数据结构引进 0数据结构相关概念 0.1什么是数据结构 数据结构是由“数据”和“结构”两词组合而来。 什么是数据?常见的数值1、2、3、4…、教务系统⾥保存的用户信息(姓名、性别、年龄、学历等等)、网页肉眼可以看到的信息(⽂字…

单元测试总结

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 Hello!大家好,我是一个专注于分享软件测试干货的测试开发。 对于软件测试,我们先按照开发阶段来进行划分,将软件测…

immaculate C# DragDrop 注册失败 解决 C#窗口程序如何看控制台打印的日志

C# DragDrop 注册失败 System.InvalidOperationExceptionHResult0x80131509MessageDragDrop 注册失败。SourceSystem.Windows.FormsStackTrace:在 System.Windows.Forms.Control.SetAcceptDrops(Boolean accept)在 System.Windows.Forms.Control.OnHandleCreated(EventArgs e)…

怎样衡量电阻负载的好坏

电阻负载的好坏通常通过以下几种方法来衡量: 1. 测量电阻值:最直接的方法是使用万用表来测量电阻负载的电阻值。将万用表设置在适当的电阻档位,然后将测试笔连接到电阻负载的两个引脚上。如果电阻负载是好的,那么万用表应该显示一…

酒蒙子骰子小程序系统

酒蒙子流量变现小程序小游戏 后端tp8 前端uniapp 会员变现 分销推广 流量主 …

Spring Boot 3.x:自动配置类加载机制的变化

随着 Spring Boot 3.x 版本的发布,Spring Boot 引入了一些关键的变更。其中最重要的一项变更是 自动配置类的加载机制。在之前的版本中,Spring Boot 使用 spring.factories 文件来管理自动配置类的加载。然而,在 Spring Boot 3.x 中&#xff…

网络安全学习路线

《网络安全自学教程》 网络安全这几年改成了网络空间安全,因为网络空间也是国家主权之一,网络空间不安全,你就要在别人眼皮子底下裸奔,当然,非洲的小伙伴就不用担心受到威胁,毕竟他们连网都没有。 网络安全…

【Linux网络编程】第十一弹---HTTP协议全解析:从请求响应到方法与Header的详尽指南

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【Linux网络编程】 目录 1、HTTP 协议 1.1、认识 URL ​1.2、urlencode 和 urldecode 1.3、HTTP 协议请求与响应格式 1.3.1、代码…

从 Router 到 Navigation:HarmonyOS 路由框架的全面升级与迁移指南

在本教程中,我们深入探讨了 Router 和 Navigation 在 HarmonyOS 中的用法差异及如何从 Router 切换到 Navigation 的方法。重点涵盖了页面跳转、转场动画、生命周期管理以及跨包路由的实现。 页面结构对比 Router 页面结构 每个页面需要使用 Entry 注解。 页面需要…

账号下的用户列表表格分析

好的,这是您提供的 el-table 组件中所有列的字段信息,以表格形式展示: 列标题 (label)字段属性 (prop)对齐方式 (align)宽度 (width)是否可排序 (sortable)说明IDidcenter100否管理员的唯一标识符头像avatarcenter90否管理员的头像 URL 或路…

luckysheet与superslide冲突解决

[现象]控制台报错、界面无法操作 $是jquery。查看源码,发现mousewheel方法来自插件mousewheel,luckysheet初始应该会将mousewheel挂载在jquery上。 在控制台打印jquery取dom及其方法,结果如下: 不存在mousewheel方法&#xff0c…

windows使用python写的YOLO来实现目标识别

使用labelImg标注,YOLO进行目标训练 一、labelImg工具下载及使用1、下载labelImg(目标标注工具[【点我下载】](https://github.com/HumanSignal/labelImg))2、使用labelImg 二、下载及使用YOLO1、下载及使用ultralytics(volo[点击…

Java——多线程(上)

一 (线程的介绍) 1 多线程的基本概念 (每个进程由三部分构成——>CPU,Data,Code,进程之间完全独立,内存隔离) (运行在进程内的,一个进程可以包含多个线程,线程之间是可以并行的,并且共享相…

SpringBoot3+graalvm:整合并打包为可执行文件

原文网址:SpringBoot3graalvm:整合并打包为可执行文件-CSDN博客 简介 本文介绍SpringBoot3如何整合graalvm,并打包为可执行文件。Windows和Linux都打包。 版本 springboot3.3.6 graalvm21(包含JDK21(21是最新的LT…

【Bolt.new + PromptCoder】三分钟还原油管主页

【Bolt.new PromptCoder】三分钟还原油管主页 PromptCoder官网:PromptCoder Bolt官网:https://bolt.new/ Bolt 是什么? Bolt.new 是一个提供创建全栈网络应用服务的平台。它允许用户通过提示(Prompt)、运行&#x…

ubuntu下anconda装pytorch

1、禁用nouveau sudo vim /etc/modprobe.d/blacklist.conf 在文件最后部分插入以下两行内容 blacklist nouveau options nouveau modeset0 更新系统 sudo update-initramfs -u 重启系统 2、装nvidia驱动 卸载原来驱动 sudo apt-get remove nvidia-* (若安装…

QT数据库(四):QSqlRelationalTableModel 类

关系数据库概念 例如下列departments、majors、studInfo 这 3 个数据表之间存在关系。 主键与外键 标记“**”的是主键字段,标记“*”的是外键字段。主键字段是一个数据表中表示记录唯一性的字段,例如 studInfo 数据表中的 studID 字段。外键字段是与其…

【Linux】-学习笔记10

第八章、Linux下的火墙管理及优化 1.什么是防火墙 从功能角度来讲 防火墙是位于内部网和外部网之间的屏障,它按照系统管理员预先定义好的规则来控制数据包的进出 从功能实现角度来讲 火墙是系统内核上的一个模块netfilter(数据包过滤机制) …

SpringBoot 手动实现动态切换数据源 DynamicSource (中)

大家好,我是此林。 SpringBoot 手动实现动态切换数据源 DynamicSource (上)-CSDN博客 在上一篇博客中,我带大家手动实现了一个简易版的数据源切换实现,方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源…