Volatile关键字简述

news2024/11/25 18:36:35

Volatile关键字

  • 前言
  • 前置知识
    • 程序、进程、线程
      • 程序
      • 进程
      • 线程
    • 并发所涉及的一些特性
      • 线程安全
      • 原子性
      • 可见性
    • Volatile
  • 案例
    • 环境
    • 代码展示
      • 可见性测试
      • 原子性测试

前言

最近在看《Java并发编程实战》,期望对一些并发的知识点做一些总结。最好有一定的Java基础、并发的基础。

前置知识

程序、进程、线程

程序

程序是静态的代码块。

进程

进程是动态的,是程序运行之后的产物,同时进程是资源分配的最小单元。

线程

线程是对进程进一步细化,因为CPU的数量限制了进程的数目,为了适应更大的吞吐量,线程就产生了。同属于一个进程的线程共享该进程的资源,是操作系统进行调度的最小单元。

并发所涉及的一些特性

线程安全

多个线程同时访问某个资源的时候,不需要额外同步,都能保证结果的正确性。

原子性

代码块运行期间不会受到外部的影响,即该代码块是不可分割的最小的操作单元。

可见性

某个线程修改了共享的数据单元之后,能够立即通知到其他线程。

Volatile

相比synchronized(重量级同步),Volatile是轻量级同步锁,方便了并发编程,常用在信号量来控制程序执行逻辑,但是过度依赖volatile变量会使得使用锁的代码更脆弱,难以理解。

相比于synchronized,Volatile读取的时候不会加锁,所以不能保证线程安全。

Volatile能够保证可见性,无法保证原子性,参见下面的例子。

案例

环境

maven3.X、JDK17

代码展示

可见性测试

没有volatile,这时候如果自增发生在while循环取得num之后,就会导致死循环。

    // 可能死循环
    static int num1 = 1;
    
    /**
     * 可能死循环
     */
    @Test
    public void atomTest1() {
        new Thread (VolatileTest::addNumByOne1).start ( );
        while (num1 < 2) {
        }
        System.out.println (num1);
    }

    static void addNumByOne1() {
        try {
            TimeUnit.SECONDS.sleep (1);
        } catch (InterruptedException e) {
            throw new RuntimeException (e);
        }
        num1++;
    }

通过Volatile保证了无论何时在其他线程修改num之后,主线程能够正确的读取修改之后的num值,以跳出循环

    // 可见性,一旦修改 就通知
    static volatile int num2 = 1;

    /**
     * 可见性体现
     */
    @Test
    public void atomTest2() {
        new Thread (VolatileTest::addNumByOne2).start ( );
        while (num2 < 2) {
        }
        System.out.println (num2);
    }
    
	static void addNumByOne2() {
	       try {
	           TimeUnit.SECONDS.sleep (1);
	       } catch (InterruptedException e) {
	           throw new RuntimeException (e);
	       }
	       num2++;
	   }

原子性测试

这里很容易以为最好打印出的结果是20000,因为volatile保证了可见性,那么每个线程都能获取到其他县城修改之后的num,进行+1。但是结果大多数都是小于20000的。

    // 原子性
    static volatile int num3 = 1;
     
     /**
     * 不能保证原子性
     */
    @Test
    public void atomTest3() throws InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool (10);
        for (int i = 0; i < 10; i++) {
            pool.submit (new Thread (() -> {
                for (int j = 0; j < 2000; j++) {
                    addNumByOne3();
                }
            },"t" + i));
        }
        pool.shutdown ();
        pool.awaitTermination (1,TimeUnit.SECONDS);
        System.out.println (num3);
    }

    static void addNumByOne3() {
        num3++;
    }

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

产生这个结果的原因就是,当某个线程获取到了num3,准备自增的时候,别的线程也读取到了这个num3, 也发生了自增,最后写入内存,那么本来应该增加了2,现在可能只增加了1。具体点说当前num3更新到了3,这时候t1读取到了num3准备更新的时候并不会阻止t2来读取num3,这时候两个num3处于相同的数值3,之后t1,t2各自执行num3+1,写回内存,那么自然最后更新的结果就出现了问题了。

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

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

相关文章

Qt 一个信号对应多个槽,多个信号对应一个槽的执行顺序

前言&#xff1a; Qt独创的信号槽机制&#xff0c;不仅可以一个信号连接一个槽&#xff0c;而且可以一对多或多对一。 这其中存在两个最基本的问题&#xff1a; 1.一个信号对应多个槽时&#xff0c;槽函数的执行顺序是怎样的&#xff1f;&#xff1f;&#xff1f; 2.多个信号对…

【操作系统三】图解网络IO(bio\nio\slect\epoll)

【操作系统三】图解网络IO实战一、计算机组成二、系统中断三、晶振&#xff08;时间中断、分时复用&#xff09;四、事件中断1、DMA2、事件中断3、网卡也会产生中断&#xff1f;五、linux系统知识1、linux下一切皆文件&#xff1f;1.1、nc启动一个服务端,端口号80801.2、linux下…

vulnhub靶机:matrix:1

目录 查看靶机的ip 开放端口扫描 解密 字典生成爆破 ssh登录 rbash逃逸 下载地址&#xff1a;Matrix: 1 ~ VulnHub Kali地址&#xff1a;192.168.174.128 靶机地址&#xff1a;192.168.174.139 这个靶机是我在刷到的一个视频&#xff0c;讲解这个靶机的博主比较有趣&a…

web网页设计期末课程大作业:水果网站设计——HTML+CSS+JavaScript水果超市(带论文)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

大一学生Web课程设计 HTML+CSS保时捷汽车介绍(可以很好的应付老师的作业)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

2022CTF培训(八)ARM PWN 环境搭建ARM PWN 入门

附件下载链接 环境搭建 QEMU qemu是一款可执行硬件虚拟化的虚拟机&#xff0c;与他类似的还有Bochs、PearPC&#xff0c; 但qemu具有高速&#xff08;配合KVM&#xff09;、跨平台的特性 qemu主要有两种运行模式&#xff1a;qemu-user 和 qemu-system qemu-system 可以进行…

[附源码]Python计算机毕业设计高校互联网班级管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

[附源码]Nodejs计算机毕业设计基于的开放式实验室预约系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

k8s编程operator实战之云编码平台——④web后端实现

文章目录1、简介1.1 目录结构1.2 开发模式2、数据库设计2.1 user表2.2 space_template和space_kind表2.3 space和spacespec表3、gRPC客户端4、数据库访问4.1 mysql4.2 redis5、缓存加载5.1 通用缓存5.2 数据加载6、功能开发6.1 用户登录6.2 获取所有模板6.3 创建工作空间6.4 创…

如何进行C++动态转换

&#x1f4d2;博客主页&#xff1a; ​​开心档博客主页​​ &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由开心档原创&#xff01; &#x1f4c6;51CTO首发时间&#xff1a;&#x1f334;2022年12月12日&#x1f334; ✉…

如何评价「仙剑奇侠传六」使用Unity 3D引擎?

2022年看到问题&#xff0c;根据2022年Unity3D、Unreal Engine及仙剑六来一波“穿越马后炮式”回答。 1&#xff1a; 2022年看到问题&#xff0c;根据2022年Unity3D、Unreal Engine及仙剑六来一波“穿越马后炮式”回答。 1&#xff1a; 仙剑奇侠传六确为unity引擎制作&#…

大学生简单静态HTML网页模板源码——家乡介绍美丽乡村11页

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

【leetcode】将有序数组转换为二叉搜索树

一、题目描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例 1&#xff1a; 输入&#xff1a;nums …

微信对接chatGPT,实现自动回复消息、在线答疑等功能

前言 近来chatGPT挺火的&#xff0c;也试玩了一下&#xff0c;确实挺有意思。这里记录一下在在微信中也可以使用chatGPT&#xff0c;顺带可以自动回复微信消息、实时答疑等。。。 上一篇文章回顾&#xff1a;https://frica.blog.csdn.net/article/details/128316712 本文章在u…

Spark3.3.0的DataFrame及Spark SQL编程的性能对比【单机模式下】

Spark3.3.0的DataFrame及Spark SQL编程的性能对比【单机模式下】 前言 Spark3.3.0较老早的2.4.0有极大的性能优化&#xff0c;尤其是对SQL做了大量的优化【数据倾斜等】&#xff0c;恰好近期遇到一些性能问题&#xff0c;特意写个Demo测试下DataFrame和Spark SQL在获取到相同…

c#入门-接口的抽象成员和虚成员

接口的抽象成员 接口的成员如果不指定主体&#xff0c;那么就是抽象成员。 你可以主动为他们加抽象修饰符&#xff0c;不过没什么用。 interface I属性 {public abstract int Hp { get; set; }public abstract int Mp { get; set; } }接口的虚成员 接口的成员可以指定主体。…

Jina 开箱即用的云原生多模态系统解决方案

Jina 是一个基于云原生的多模态应用框架&#xff0c;开发者使用 Jina 可以轻松构建、部署和维护高性能的云原生应用。你可能认为这些都只是空泛的营销口号&#xff0c;甚至产生疑问&#xff0c;到底什么是云原生&#xff1f;对构建多模态应用有什么帮助&#xff1f;它是否只是 …

Linux CentoOs7中用命令打开并修改文本文件

概述&#xff1a;VI/VIM VI 是 Unix 操作系统和类 Unix 操作系统中最通用的**文本编辑器**。 VIM 编辑器是从 VI 发展出来的一个性能更强大的**文本编辑器**。可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。VIM 与 VI 编辑器完全兼容。 我们常常用vim命令…

C#语言实例源码系列-实现热键屏幕和设置热键

专栏分享点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断反思前进的过程。在这个过程中…

C++ 初阶 文件操作和io流

作者&#xff1a;小萌新 专栏&#xff1a;C初阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;简单介绍C中的文件操作和io流 文件操作和io流C语言中的输入和输出流是什么&#xff1f;Cio流C标准io流C中流的特性C文件io流以二进制形…