【java解决线程间变量不可见性的方案】

解决线程间变量不可见性的方案

一、 背景

所有的实例变量和类变量都存储在主内存,但每个线程都有自己的工作内存,保留了主内存的共享变量的副本,线程修改的是共享变量,但是每个线程每次只能读取工作内存里的值,所以会导致变量不可见

示例代码:

public class visibilityDemo extends Thread{public static void main(String[] args) {visibilityTest vt=new visibilityTest();vt.start();while(true){if(vt.isFlag()){System.out.println("主线程可以看到改动值");}}}
}
class visibilityTest extends Thread{private boolean flag=false;@Overridepublic void run(){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}flag=true;System.out.println("子线程将flag改为:"+flag);}public boolean isFlag(){return flag;}
}

结果主线程无法看到flag的变化:
在这里插入图片描述

二、解决方案

1、加锁

做法:在访问共享变量之前,为包含共享变量的类加锁;
原理:加锁后,会清空线程的工作内存,被锁保护的所有字段会从主内存中重新读取到工作内存,释放锁后,会将这个线程工作内存的共享变量全部刷新回主内存,实现线程间变量可见
示例代码:

while(true){synchronized (visibilityTest.class){if(vt.isFlag()){System.out.println("主线程可以看到改动值");}}}

结果:
在这里插入图片描述

2、使用volatile关键字

原理:当有线程改变了主内存中的共享变量值的时候,会立刻同步到主内存中去,其他线程线程若使用共享变量,选择直接去主内存读取,实现线程间变量可见值,不去工作内存中读取
做法:给变量前加volatile关键字
示例代码:

private volatile boolean flag=false;

结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WAF攻防-信息收集识别被动探针代理池仿指纹白名单

知识点 0、WAF介绍&模式&识别&防护等 1、信息收集-被动扫描&第三方接口 2、信息收集-基于爬虫&文件目录探针 3、信息收集-基于用户&代理池&白名单章节点 WAF绕过主要集中在信息收集,漏洞发现,漏洞利用,权限控制…

图像处理的魔法师:Pillow 库探秘

文章目录 图像处理的魔法师:Pillow 库探秘第一部分:背景介绍第二部分:库是什么?第三部分:如何安装这个库?第四部分:库函数使用方法第五部分:场景应用第六部分:常见Bug及解…

【Day 3】Ajax + Vue 项目、路由 + Nginx

1 Ajax Asynchronous JavaScript And XML 异步的 JavaScript 和 XML 作用: 数据交换 通过 Ajax 可以给服务器发送请求,并获取服务器响应的数据 异步交互 可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术&#xf…

代码随想录 797. 所有可能的路径

题目 给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序) graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一…

【R语言】混合图:小提琴图+箱线图

{ggstatsplot} 是 {ggplot2} 包的扩展,用于创建图形,其中包含信息丰富的绘图本身中包含的统计测试的详细信息。在典型的探索性数据分析工作流程中,数据可视化和统计建模是两个不同的阶段:可视化通知建模,而建模又可以建…

结构体输出字符串末尾有奇怪字符

今天打开之前的陈年老题,发现一个思路全对,但是答案错误的简单结构体的题,发现这个字符串输出末尾有奇怪字符,后来经过一番搜索发现,是因为给字符串定义的时候分配的空间不够,所以多分配一些就好啦 修改后&…

使用prompt_toolkit构建交互式命令行工具

prompt_toolkit是一个python库,用于构建命令行工具和终端应用。其官网介绍如下, prompt_toolkit is a library for building powerful interactive command line and terminal applications in Python. 安装命令如下, pip install prompt_to…

AJAX——图书管理案例

1.渲染列表 自己的图书数据:给自己起个外号,并告诉服务器,默认会有三本书,基于这三本书做数据的增删改查。 // 目标1:渲染图书列表 // 1.1 获取数据 // 1.2 渲染数据const creator 哈哈 // 封装-获取并渲染图书列表函…

如何在本地服务器部署TeslaMate

文章目录 1.主要参考官方文档2.准备文件:docker-compose.yml3.运行4.成功后4.1 在这个链接,更具提示登录4.2 在这个链接可以看到电池健康和行车数据等 5.后续说明6.进行数据备份6.1 先将数据进行备份,参考链接6.2 数据迁移6.3 下图为我挂该数…

C++修炼之路之多态--多态的条件与例外,重载+重写+重定义

目录 前言 一:构成多态的条件及一些特殊情况(前提是构成父子类) 1.多态是在不同的继承关系的类对象,去调用同一函数,产生了不同的结果 2.两个条件 3.三同的两个例外 1.协变---返回值类型可以不同,但必…

JVM类加载基本流程及双亲委派模型

1.JVM内存区域划分 一个运行起来的Java进程就是一个JVM虚拟机,这就需要从操作系统中申请一片内存区域。JVM申请到内存之后,会把这个内存划分为几个区域,每个区域都有各自的作用。 一般会把内存划分为四个区域:方法区(也称 "…

【C++提高】常用容器

常用容器 引言:迭代器的使用一、vector容器1. vector基本概念2. vector的迭代器3. vector构造函数4. vector赋值操作5. vector容量和大小6. vector插入和删除7. vector数据存取8. vector互换容器9. vector预留空间 二、deque容器1. deque容器的基本概念2. deque容器…