解决可见性的方案有哪几种,你都知道吗???

news2024/9/21 2:32:54

1. 前言

上次【保证原子性的几种方式,你都知道吗???】 经过一顿大杂烩后,列举了几种原子性的解决方案。这次我们继续上次的话题,我们来说说可见性的解决方案。废话不多说,让我们赶快开始吧。

2. 什么是可见性。

让我们用一张图带你了解下什么是可见性。

image.png
可见性问题是基于CPU位置出现的,CPU处理速度非常快,相对CPU来说,去主内存获取数据这个事情太慢了,CPU就提供了L1,L2,L3的三级缓存,每次去主内存拿完数据后,就会存储到CPU的三级缓存,每次去三级缓存拿数据,效率肯定会提升。

这就带来了问题,现在CPU都是多核,每个线程的工作内存(CPU三级缓存)都是独立的,会告知每个线程中做修改时,只改自己的工作内存,没有及时的同步到主内存,导致数据不一致问题。

3. 哪几种方式解决可见性呢???

3.1 volatile

  • volatile核心语义:
    • volatile属性被写:当写一个volatile变量,JMM会将当前线程对应的CPU缓存及时的刷新到主内存中
    • volatile属性被读:当读一个volatile变量,JMM会将对应的CPU缓存中的内存设置为无效,必须去主内存中重新读取共享变量

总之就是一句话:读的时候直接到主内存中获取值。写的时候将CPU缓存中的数据强制同步到主内存中去

public class T08_Thread_Volatile {

    private static volatile boolean flag = true;

    public static void loop() {
        while (flag) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(T08_Thread_Volatile::loop);

        t1.start();
        Thread.sleep(2000);

        flag = false;
    }
}

3.2 synchronized

synchronized也是可以解决可见性问题的

如果涉及到了synchronized的同步代码块或者是同步方法,获取锁资源之后,将内部涉及到的变量从CPU缓存中移除,必须去主内存中重新拿数据,而且在释放锁之后,会立即将CPU缓存中的数据同步到主内存

public class T09_Thread_synchronized {

    private static boolean flag = true;

    public static void loop() {
        while (flag) {
            synchronized (T09_Thread_synchronized.class) {

            }
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(T09_Thread_synchronized::loop);
        t1.start();

        Thread.sleep(2000);
        flag = false;
    }
}

3.3 lock锁

Lock锁保证可见性的方式和synchronized完全不同,synchronized基于他的内存语义,在获取锁和释放锁时,对CPU缓存做一个同步到主内存的操作

Lock锁是基于volatile实现的。Lock锁内部再进行加锁和释放锁时,会对一个由volatile修饰的state属性进行加减操作

如果对volatile修饰的属性进行写操作,CPU会执行带有lock前缀的指令,CPU会将修改的数据,从CPU缓存立即同步到主内存,同时也会将其他的属性也立即同步到主内存中。还会将其他CPU缓存行中的这个数据设置为无效,必须重新从主内存中拉取(缓存一致性协议)

public class T10_Thread_Lock {
    private static boolean flag = true;
    private static Lock lock = new ReentrantLock();

    public static void loop() {
        while (flag) {
            try {
                lock.lock();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(T10_Thread_Lock::loop);
        t1.start();

        Thread.sleep(1000);
        flag = false;
    }
}

3.3.1 源码查找如下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 结论

以上就是可见性的实现方案。第一种跟最后一种原则上大致相同。但是第二种不太一样。好了,今天的分享就到这里了。如果大家觉得还可以的话,记得点赞收藏哦.

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【阶段二】Python数据分析Pandas工具使用10篇:探索性数据分析:数据的检验:正态性检验

本篇的思维导图: 探索性数据分析:数据的检验 数据检索,则是对数据深层次的探索或挖掘,用于验证数据是否服从某种假设,这部分内容将以数据的正态性检验、卡方检验和t检验为例,结合Python讲解具体的使用方法。 正态性检验 统计学中的很多模型或检验都需要…

java旅游日志博客系统旅行记录系统

简介 记录个人旅游动态日志的系统,也可以用来做博客系统,主页可以发布旅游日志,关注博主,给博主留言,管理评论,博文点赞,个人主页。 演示视频 https://www.bilibili.com/video/BV1rv41147W1/?…

(深度学习快速入门)第三章第三节1:深度学习必备组件之数据集处理和参数初始化

文章目录一:数据集的处理(1)数据集划分(2)数据集验证(3)标准化和归一化二:模型参数的初始化(1)梯度消失和梯度爆炸(2)模型参数初始化方…

Kafka概述

Kafka入门-1 视频资料,b站:https://www.bilibili.com/video/BV1eD4y1C7uM/?spm_id_from333.788.recommend_more_video.14&vd_source37596bc6f952081640b3f38ea9f6a2cb 深入理解 Kafka: 核心设计与实践原理。PDF 书资料: https://book.…

P8第一讲(选修):反向传播Backpropagation

8. 第 1 讲(选修):反向传播_哔哩哔哩_bilibili Gradient Descent neual work基本架构已经学过了 backpropagation(反向传播)可以帮助我们有效的进行渐变迭代计算(帮助计算梯度)。 假设网络有一大堆参数: 首先选一个初始的参数&…

零基础多图详解图神经网络(GNN/GCN)【论文精读】

原文链接: A Gentle Introduction to Graph Neural Networks (distill.pub) 我们不仅仅关系整个图的架构,其实我们更关心的是每个顶点每条边和整个图所表示的信息。 我们如何把我们想要的信息表示成以上这些向量,以及这些向量是否能够通过数据…

uni-app打开第三方地图软件进行导航

最近在开发字节小程序的过程中遇到地图导航的需求,相信大家也会遇到所以我为大家整理了一篇干货内容。 下面是我整理的代码案例---------记得喝水(太“干”了,复制就能用)。 效果图如下: 1.点击图标弹出弹框进行选择…

数据结构与算法基础——算法分析(1)

算法的定义 算法:对特定问题的求解方法和步骤的描述,在计算机中,他是指令的有限集合。 举例:求解一元二次方程的根 描述算法的基本方式: (1)自然语言 (2)流程图 &…

CSS3 弹性盒子(flex、flex-direction属性、flex-wrap属性、align-items属性、align-content属性)详解

文章目录flexflex-direction 属性flex-wrap 属性align-items 属性align-content 属性的使用flex 在 CSS3 中给 display 属性增加了新的属性值 flex,如果一个元素被设置 display:flex,说明该元素为弹性布局,也就是个弹性盒子。 flex 主要由两…

Linux traceroute 原理及使用

Linux traceroute 原理及使用 序 在某次接入数据的场景中,需要到对方 SFTP 服务器上,获取数据,但是在配置时发现在配置正确的情况下, 连接总是超时,最终排查后发现网络不通,打通网络后才正确连接&#xf…

【C++】函数重载

函数重载1.函数重载的背景2.函数重载的概念2.1参数类型不同的重载2.2参数个数不同的重载2.3参数类型顺序不同的重载2.4注意事项:仅仅是返回值不同无法构成函数重载3.C函数重载的原理---函数名字修饰4.函数重载总结1.函数重载的背景 在C语言中,我们写一个…

通信原理 | 基本概念

1 通信及通信系统 通信(Communication)是实现信息和消息传输的过程 通信系统(Communication System)的组成: 实现通信的所有硬件和软件设备、传输媒介以及各种通信协议等 消息(Message)、信息(Information)、信号(Signal)的区别: 消息通常指人的感官能够感受到的…

无刷电机高压与低压的选择与未来发展前景

近几年来,伴随无刷马达被戴森吸尘器全力以赴运用在家用电器上,颠覆了传统家电的3个产品运用场景,吹风筒就是这样的一个例子。 迅速风筒由于其加工工艺的创新能力,给大家增添了不一般的产品体验度。新型的迅速风筒,搭配…

2023我的前端面试小结

对事件委托的理解 (1)事件委托的概念 事件委托本质上是利用了浏览器事件冒泡的机制。因为事件在冒泡过程中会上传到父节点,父节点可以通过事件对象获取到目标节点,因此可以把子节点的监听函数定义在父节点上,由父节点…

Elasticsearch:利用搜索提高医疗保健公平 - 用多语言 NLP 模型和分析来改善最终用户体验

随着更高生产力和更健康的人群寿命更长,医疗保健将成为社会最重要的方面之一。 COVID-19 大流行加速了现代技术的采用,并凸显了患者体验的重要性。 随着越来越多的消费者开始控制他们的数据,医疗保健系统变得捉襟见肘。 根据德勤和斯科茨代尔…

【High 翻天】Higer-order Networks with Battiston Federico (5)

目录扩散高阶扩散题外话高阶随机游走扩散 在给出建模之后,接下来讨论如何将传统意义下的扩散拓展到高阶系统。扩散是一个线性过程,但在许多不同的情况下都有强相关性。扩散这个词实际可指代两个不同的过程: 标准的扩散过程,或者…

课题-基于安卓androidstudio的校园外卖app

一、课题介绍 客户端: 1:登录注册:用户可以通过自己的信息进行账号的注册 2:商家搜索:可以对商家的信息进行模糊搜索 3:查看菜单:点击商家可以查看具体的菜单信息 4:添加购物车&…

SAP FICO 财务月结--自动清账

一、基本概念 清账是会计科目的借贷挂账后的核销,其中包括客户、供应商以及实行未清账管理的总账科目等。 客户和供应商的清账通常会在收款或者付款的时候同时完成,也就是边收边清或者边付边清,也可以后续手工清账(客户F-32&…

人脸清晰化神器codeFormer图形界面包GUI

1. codeFormer介绍 在NeurIPS 2022上,南洋理工大学-商汤科技联合研究中心S-Lab提出了一种基于VQGANTransformer的人脸复原模型CodeFormer,效果是真的强大,先展示下效果,用的官方案例效果图。 官方给出的代码见这里 传送门 2. 图…

Python数组存储方式与向量化、按行按列展平/展开

文章目录1 逻辑存储与内存存储1.1 高维张量1.2 按行展开和按列展开2 矩阵向量化、按行按列展开2.1 numpy中:numpy.ravel()ndarray.flatten()2.2 Pytorch中:3 pytoch中的view,reshape,permute对比3.1 view3.2 reshape3.3 permute链…