首页 > 其他分享 >synchronized和volatile区别

synchronized和volatile区别

时间:2023-06-13 18:55:53浏览次数:42  
标签:变量 synchronized 区别 保证 线程 内存 volatile

synchronized和volatile区别
个人理解JMM:Java Memory Model(Java内存模型),根据并发过程中如何处理、可见性、原子性和有序性这三个特性而建立的模型。
可见性:JMM提供了volatile变量定义、final、synchronized块来保证可见性。
原子性:个人理解是如果执行,就执行完,synchronized块来保证。
有序性:觉得有序是相对性的,根据从哪个线程观察,volatile和synchronized保证线程之间操作的有序性。
指令重排:处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证各个语句的执行顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。指令重排序不会影响单个线程的执行,但是会影响到线程并发执行的正确性。
JMM处理过程:JMM是通过禁止特定类型的编译器重排序和处理器重排序来为程序员提供一致的内存可见性保证。例如A线程具体什么时候刷新共享数据到主内存是不确定的,假设我们使用了同步原语(synchronized,volatile和final),那么刷新的时间是确定的。


每个线程都有一个自己的本地内存空间–虚拟机栈线程空间。线程执行时,先把变量从主内存读取到线程自己的本地内存空间,然后再对该变量进行操作
对该变量操作完后,在某个时间再把变量刷新回主内存,所以线程A释放锁后会同步到主内存,线程B获取锁后会同步主内存数据,即“A线程释放锁–B线程获取锁”可以实现A,B线程之间的通信

稍微解释下:
假设本地内存A和B有主内存中共享变量x的副本,初始时这三个内存中的x值都为0。线程A在执行时,把更新后的x值(假设值为1)临时存放在自己的本地内存A中。当线程A和线程B需要通信时,线程A首先会把自己本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。然后,线程B到主内存中去读取线程A更新后的x值,此时线程B的本地内存的x值也变为了1。
建议了解下线程的生命状态,这里就不多做解释,面试的时候很有可能会被问到。

重点:

volatile主要应用在多个线程对实例变量更改的场合,刷新主内存共享变量的值从而使得各个线程可以获得最新的值,线程读取变量的值需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。另外,synchronized还会创建一个内存屏障,内存屏障指令保证了所有CPU操作结果都会直接刷到主存中(即释放锁前),从而保证了操作的内存可见性,同时也使得先获得这个锁的线程的所有操作
volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的。
volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞,比如多个线程争抢synchronized锁对象时,会出现阻塞。
volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性,因为线程获得锁才能进入临界区,从而保证临界区中的所有语句全部得到执行。
volatile标记的变量不会被编译器优化,可以禁止进行指令重排;synchronized标记的变量可以被编译器优化。
————————————————
版权声明:本文为CSDN博主「会飞的狗~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaoming100001/article/details/79781680

标签:变量,synchronized,区别,保证,线程,内存,volatile
From: https://www.cnblogs.com/huigui-mint/p/17478485.html

相关文章

  • MATLAB-histcounts和hist的区别
    N=hist(X,Y)表示把X放进Y桶里面例如X=[1,2,3,4];Y=[2,3.5];Y里面装的,是桶的中心换成区间实际上是:\([-inf,\frac{2+3.5}{2}),[\frac{2+3.5}{2},inf)\)所以,X里的1、2在第一个区间,3、4在第二个区间,输出N=[2,2]若X=[0,1,2,3],输出N=[3,1]histcounts与hist用法差不......
  • 谈抽象类与接口的区别之一
    评:谈抽象类与接口的区别之一一、抽象类:抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的......
  • C++中malloc/free与new/delete的区别与联系
    原文:https://blog.csdn.net/u010510020/article/details/76266505 一、用法:  用malloc申请一块长度为length的整数类型的内存,程序如下:   int*p=(int*)malloc(sizeof(int)*length);   我们应当把注意力集中在两个要素上:“类型转换”和“sizeof”。 ......
  • kettle和Flink做ETL的区别
    Kettle和Flink都可以用于ETL(抽取、转换和加载)处理,但它们有一些不同之处。Kettle是一款基于图形化界面的ETL工具,可以通过拖放组件的方式来设计和构建ETL流程。它提供了大量的内置组件和步骤,可以用于处理各种数据源和格式。Kettle的优点是易于使用和学习,适合于小型数据处理任务和快......
  • C/C++ include 头文件的语句中,双引号和尖括号的区别
    #include指令有两种使用形式#include<stdio.h>文件名放在尖括号中#include“mystuff.h”文件名放在双引号中 双引号"xxx.h",表示编译器先在用户的工作目录下搜索头文件,如果搜索不到则到系统默认目录下去寻找,所以双引号一般用于包含用户自己编写的头文件。如:#include"stu......
  • I2C总线与SMbus总线的区别
    本文转载自: 彻底搞懂I2C总线(4)I2C总线的其他用途(baidu.com)摘要本章节阐述了I2C总线的其他用途,如用于CBUS总线、SMBUS总线、PMBUS总线、IPMI接口、ATCA通信、DDC通信等。四.I2C总线通信协议的其他用途I2C总线被用作多种系统结构的通信协议。除了基本的I2C规范之外,这......
  • html中href和src的区别?
    一省:HTML3.html中href和src的区别?href:href是HypertextReference的缩写,表示超文本引用。用来建立当前元素和文档之间的链接。常用的有:link、a。例如:<linkhref="style.css"rel=”stylesheet“/>浏览器会识别该文档为css文档,并行下载该文档,并且不会停止对当前文档的......
  • GET和POST的区别+编码方式
    一、功能GET:从服务器上获取数据PSOT:向服务器传送数据(更新服务器资源)二、REST服务角度GET:幂等(读取同一资源,得到相同数据)===》不改变服务器上的资源POST:不是幂等(每次请求的资源的改变不同)===》改变服务器上的资源三、请求参数形式GET:请求的数据会附在U......
  • Java 实战介绍 Cookie 和 Session 的区别
    HTTP是一种不保存状态的协议,即无状态协议,HTTP协议不会保存请求和响应之间的通信状态,协议对于发送过的请求和响应都不会做持久化处理。无状态协议减少了对服务压力,如果一个服务器需要处理百万级用户的请求状态,对服务器的压力无疑的是巨大的。无状态的HTTP由于其简单和易用性......
  • 【易错点】数组名和数组取地址的区别
     inta[3]={1,2,3}; a: 数组名,数组中第一个元素的地址,相当于&a[0] &a:整个数组的地址,在数值上等于a a+1:数组中第二个元素的地址,相当于&a[1] &a+1:整个数组结束以后后面一个位置的地址 即:a=&a, 但 a+1≠&a+1 a[0]a[1]a[2]     ......