【线程知识点】--可见性_高级摸鱼工程师的博客-程序员宅基地

技术标签: 线程那点事  【线程】  多线程  可见性  

可见性

  • 可见性:一个线程对共享变量的修改,能够及时的被其它线程看到。
  • 共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。

 

Java内存模型

  • 所有的变量都存贮在主内存中
  • 每个线程都拥有自己独立的工作内存,里边保存该线程使用到的变量副本(主内存中该变量的一份拷贝)

两条规定:

  1. 线程对共享变量的所有操作都必须在自己的工作内存中进行,不可以直接操作主内存
  2. 不同线程之间无法直接访问对方工作内存中的共享变量,线程之间共享变量的传递需要通过主内存来完成。

共享变量可见性实现的原理

线程1对贡献变量的修改想要及时被线程2看到,那么必须进行如下两个步骤:

  1.  把线程1的工作内存中共享变量的值刷新到主内存中。
  2.  把主内存中共享变量的最新值更新到线程2的工作内存中。


内存可见性的实现

synchronized实现可见性

synchronized能够实现:

  • 原子性(同步,互斥锁)
  • 可见性

 

JMM对synchronized的两条规定:

  1.          线程解锁前,必须把共享变量的最新值刷新到主内存中
  2.          线程解锁时,会将工作内存中的值标注为失效,重新加锁时如果发现值失效,那么就从主内存中重新读取一次。(注意:这里指的是同一把锁

 

以上两点实现的效果:

线程解锁前对共享变量的修改,在下次加锁的时候对其他线程可见。

 

重排序

重排序:代码书写的顺序和实际执行的顺序不同,指令重排序是编译器或者是处理器为了提高程序的性能而做的优化。

具体有以下三种:

  1. 编译器优化的重排序(编译器优化)
  2. 指令级并行重排序(处理器优化)
  3. 内存系统的重排序(处理器优化)

 

as-if-serial:无论如何重排序,程序执行的结果都应该和代码顺序执行的结果一致(java编译器和处理器都会保证java在单线程下遵循as-if-serial语义)

 

int num1 = 1;
int num2 = 2;
int sum = num1 + num2;

 

单线程:第一行和第二行的顺序可以重排,但是第三行不能。

  • 重排序不会给单线程带来内存可见性的问题
  • 多线程中程序交错执行的时候,重排序就可能会带来内存可见性问题了

 

欢迎关注公众号~


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Paranoia_ZK/article/details/80300962

智能推荐

c语言中的static变量和static函数_static定义函数和变量是为了使其能够跨文件使用_(涉及版权请私聊我,立马删)的博客-程序员宅基地

在C语言中,static的字面意思很容易把我们导入歧途,其实它的修饰变量作用有三条。(1)先来介绍它的第一条也是最重要的一条:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。下面是a.c的内容char a = 'A'; // global vari

Unity手游开发札记——布料系统原理浅析和在Unity手游中的应用_unity 布料_子胤的博客-程序员宅基地

原文:https://zhuanlan.zhihu.com/p/286446180. 前言项目技术测试结束之后,各种美术效果提升的需求逐渐成为后续开发的重点,角色效果部分的提升目标之一便是在角色选择/展示界面为玩家提供更高的品质感,于是可以提供动态效果的布料系统就作为了技术预研的方向。笔者在之前的端游项目中有较多使用布料系统制作布料效果的经验,这次也尝试了在Unity引擎中进行布料效果制作...

ROS 教程3 机器人语音 语音识别理解合成控制 ASR NLU TTS_asr nlu_EwenWanW的博客-程序员宅基地

一、语音处理总体框架 1. 语音识别(ASR , Automatic Speech Recognition ) 2. 语义理解(NLU , Natural Language Understanding) e. 语音合成(TTS , Text To Speech)1. 语音识别 **ASR**:支持的包: 国外:CMU SPhinx ——> pocket...

C++ 中stringstream 的作用_stringstream作用_南friend的博客-程序员宅基地

C++中标准IO库有三大类 iostream :  支持对标准输入输出设备(键盘,显示器)的读写;fstream: 支持对文件的读写;stringstream: 支持对string 对象更灵活的处理;一.       stringstream 一般可以用来实现安全的数据类型转换:以int 类型为例1.  int 类型转string 类型  int

通信(1)----Http协议的方法讲解_http协议通信的时序图_zhangbijun1230的博客-程序员宅基地

Http协议的方法讲解HTTP协议请求相应中有8个不同的请求方法:分别是Get、POST、HEAD、PUT、DELETE、OPTIONS、TRACE和CONNECT;1. GET方法[plain] view plain copy 它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。  GET请求中,永远不会包含呈现数据...

跨端开发,flutter和react native如何选择_react native flutter_张富涛的博客-程序员宅基地

这是张富涛的第14篇原创跨端开发,flutter和react native如何选择1. 传统方案的瓶颈 和 flutter及RN要解决的问题五六年前智能手机开始逐渐普及大众,从此Android和IOS便成为移动端coder的舞台,在我还上学那会儿,“分班”的时候移动端就已经可以两端择一,那时候,如果一家企业需要做移动端,至少需要有会IOS和Android的员工,不然就会面对一个平台产品缺失和用户流失的问题,但如果都招,面临的必然是“成本较大”、“双端功能同步更新”等问题。那时候“一套代码生成双端原.

随便推点

android.view.MotionEvent的事件触发来源的问题?_android getdevice().getsource()_yingjialong2639的博客-程序员宅基地

我用的是绘王USB PEN TABLET,带了一支手写笔。public boolean onTouchEvent(android.view.MotionEvent event)  { int iDeviceId = event.getDeviceId(); int iSource = event.getSource();/*public final int getDeviceId ()

Eclipse设置虚拟机参数_eclipse vm options_小仇哥的博客-程序员宅基地

首先在Eclipse的Debug页签中设置虚拟机参数:步骤: 1、选中已经写好的项目 2、Run->Debug configurations->Java Application 双击 3、Arguments->VM arguments 4、在VM arguments 里面就可以对虚拟机的内存参数进行设置 5、设置完成后,Apply->Debug 6、过程结束采用《深入理解java

【Mysql】Linux(Ubuntu)下安装Mysql5.6.28_AskTOMmorow的博客-程序员宅基地

1.系统基本信息查看,尝试yum安装$ sudo -s# df -lhFilesystem Size Used Avail Use% Mounted on/dev/vda1 79G 1.6G 74G 3% /udev 3.9G 8.0K 3.9G 1% /devtmpfs 799M 252K 799M

手机模拟加密门禁卡 考勤卡 会员卡 停车卡 电梯卡等教程-不用电脑,无需root_yanchen0128的博客-程序员宅基地

手机模拟加密门禁卡 考勤卡 会员卡 停车卡 电梯卡等教程-不用电脑,无需root目标:将门禁卡、考勤卡、会员卡、停车卡、电梯卡等等各种卡模拟进手机里,模拟后可用手机代替刷卡,无需root,不用电脑背景介绍:1、前言  目前,IC卡已被广泛应用于身份识别、金融消费、安全认证等领域。大多数人每天都要和各种各样的卡片打交道,上班有考勤卡,吃饭有饭卡,健身有会员卡,停车有停车卡,连回个家都得先把门卡翻出来,各种各样的卡,方便我们生活的同时也为我们的生活带来一点点不便。其实NFC手机不仅可以模拟公交卡和

ESP32/ESP32S3模组在使用Touchpad例子发生flash出错问题解决方式_esp32-s3core dump flash config is corrupted_嵌入式那个小哥的博客-程序员宅基地

目前楼主使用的是ESP32S3-WROOM-1前天发现跑了一个致命问题:开发板跑examples\peripherals\touch_sensor\touch_sensor_v2\touch_pad_read这个demo,在读取线程里调用esp_light_sleep_start进入低功耗,这时候程序跑一会就出问题,该问题表现为模组启动失败,提示E (409) esp_image: Image hash failed - image is corrupt该问题比较隐蔽且致命。查找原因发现跟低功耗有关,官

推荐文章

热门文章

相关标签