不同关键字的原子性、可见性、有序性之间的比较

2024-08-23 20:36

本文主要是介绍不同关键字的原子性、可见性、有序性之间的比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、多线程中有三个非常重要的特性

1. 原子性

    在一次或者多次操作时,要么所有操作都被执行,要么所有操作都不执行

2. 有序性

    程序执行的顺序按照代码的先后顺序执行,没有进行优化和顺序调整。

    为了提高程序的运行效率,Java可能在JVM编译期和运行期会对代码指令进行一定的优化,不会百分之百的保证代码的执行顺序严格按照编写代码中的顺序执行,但也不是随意进行重排序,它会保证程序的最终运算结果是编码时所期望的。这种情况被称之为指令重排

3. 可见性

   当一个线程对共享变量进行修改后,其他一个线程可以立即看到该变量修改后的最新值

二、说到三个特性,就不得不提Java内存模型(JMM)

       JMM是一种抽象概念,并不真实存在,它描述的是一组规范。JVM运行程序的实体是线程,每个线程都有一个属于自己私有的工作内存。Java内存模型中规定了:所有变量都存储在主内存中,主内存是一块共享内存区域,所有线程都可以访问。

       但是,线程对变量的读取赋值等操作必须在自己的工作内存中进行,在操作之前先把变量从主内存中复制到自己的工作内存中,然后对变量进行操作,操作完成后再把变量写回主内存。因为线程不能直接操作主内存中的变量,所以线程的工作内存中存放的是主内存中变量的一个副本而已。

三、如何保证有序性

Java内存模型的一个叫 Happens-Before 的原则了。如果两个操作的执行顺序无法从Happens-Before原则推到出来,那么可以对它们进行随意的重排序处理了。Happens-Before原则有下面这些原则,希望你能记住:

1. 程序次序原则:一段代码在单线程中执行的结果是有序的。
2. 锁定原则:一个锁处于被锁定状态,那么必须先执行unlock操作后面才能进行lock操作。
3. volatile变量原则:同时对volatile变量进行读写操作,写操作一定先于读操作。
4. 线程启动原则:Thread对象的start方法先于此线程的每一个动作。
5. 线程终结原则:线程中的所有操作都先于对此线程的终止检测。
6. 线程中断原则:对线程interrupt方法的调用先于被中断线程的代码检测到中断事件的发生。
7. 对象终结原则:一个对象的初始化完成先于它的finalize方法的开始。
8. 传递原则:操作A先于操作B,操作B先于操作C,那么操作A一定先于操作C。
9. 除了Happens-Before原则提供的天然有序性,我们还可以用以下几种方式保证有序性:

四、总结一下

特性volatile关键字Lock接口synchronized关键字Atomic变量
原子性无法保障可以保障可以保障可以保障
可见性可以保障可以保障可以保障可以保障
有序性一定程度保障可以保障可以保障无法保障

这篇关于不同关键字的原子性、可见性、有序性之间的比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1100437

相关文章

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

Oracle Start With关键字

Oracle Start With关键字 前言 旨在记录一些Oracle使用中遇到的各种各样的问题. 同时希望能帮到和我遇到同样问题的人. Start With (树查询) 问题描述: 在数据库中, 有一种比较常见得 设计模式, 层级结构 设计模式, 具体到 Oracle table中, 字段特点如下: ID, DSC, PID; 三个字段, 分别表示 当前标识的 ID(主键), DSC 当

MyBatis 切换不同的类型数据库方案

下属案例例当前结合SpringBoot 配置进行讲解。 背景: 实现一个工程里面在部署阶段支持切换不同类型数据库支持。 方案一 数据源配置 关键代码(是什么数据库,该怎么配就怎么配) spring:datasource:name: test# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSource# @需要修改 数据库连接及驱动u

关键字synchronized、volatile的比较

关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。随着JDK新版本的发布,synchronized关键字的执行效率上得到很大提升,在开发中使用synchronized关键字的比率还是比较大的。多线程访问volatile不会发生阻塞,而synchronize