轻量级同步机制volatile

news/2024/5/17 17:22:42 标签: volatile, synchronized, 并发编程

在Java多线程编程当中,提供了以下几种方式来实现线程安全

内部锁(synchronized)和显式锁(Lock):属于互斥同步方法,是重量级的多线程同步机制,可能会引起上下文切换和线程调度,它同时提供内存可见性、有序性和原子性

介绍

volatile:轻量级多线程同步机制,不会引起上下文切换和线程调度。仅提供内存可见性、有序性保证(禁止指令重排序优化),不提供原子性

当一个变量定义为volatile之后,它将具备两个特性,第一是保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点,普通变量的值在线程间传递均需要通过主内存来完成,例如,线程A修改一个普通变量的值,然后向主内存进行回写,另外一条线程B在线程A回写完成了之后再从主内存进行读取操作,新变量值才会对线程B可见。

在这里插入图片描述

CAS原子指令(Compare And Swap):属于非阻塞同步方法,轻量级多线程同步机制,不会引起上下文切换和线程调度。它同时提供内存可见性、有序性和原子化更新保证。

synchronized修饰的对象
synchronized是Java中的关键字,是一种同步锁。它可以修饰以下几种代码片段:

方法,作用范围是整个方法,作用的对象是调用这个方法的对象;
代码块,作用范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
静态方法,作用范围是整个静态方法,作用的对象是这个类的所有对象;
类。作用范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象。

volatile_25">volatile怎样保证可见性

对于可见性,Java提供了volatile关键字来保证可见性。

当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。

并发编程(Java Memory Model)的三大特性

  • 原子性
    即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

  • 可见性
    可见性指的是多个线程对共享资源的可见性。当一个线程修改了某一资源,其他线程能够看到修改结果。

  • 有序性
    即程序执行的顺序按照代码的先后顺序执行。

synchronized锁与volatile变量的比较

volatile变量最大的优点是使用方便。在某些情形下,使用volatile变量要比使用相应的synchronized锁简单得多。
某些情况下,volatile变量同步机制的性能要优于synchronized锁。
volatile变量不会像synchronized锁一样造成阻塞。
volatile变量最大的缺点在于使用范围有限,而且容易出错。
总的来说volatile变量使用范围有限,不能替代synchronized,但在某些场景下,使用volatile更好。

计算机在执行程序时,为了提高性能,编译器和处理器常常会对指令做重排,一般分以下3种
源代码----》编译器优化的重排-----》指令并行的重排----》内存系统的重排----》最终执行的指令


推荐文档:

  1. https://blog.csdn.net/u010255818/article/details/65633033
  2. http://www.importnew.com/24082.html

http://www.niftyadmin.cn/n/1364322.html

相关文章

基于jQuery简单实用的Tabs选项卡插件

jQuery庞大的插件库总是让人欢喜让人忧,如何从庞大的插件库里挑出适合自己的插件,总是让很多缺少经验的朋友头疼的事!今天为大家推荐几款简单实用的Tabs选项卡插件,推荐理由:简单易用灵活,样式美观&#xf…

[分类问题的评估指标] Macro-F1和Micro-F1

分类问题的评估指标 在利用K_means 、LR、SVM 分类,评估Embedding 结果的好坏时,遇到如下代码: 不理解当中 micro_f1,macro_f1的含义,开此篇学习记录。 def classification(x, y, methodXGBoost):x_train, x_valid, y_…

CAS无锁算法

乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在Java和数据库中都有此概念对应的实际应用。 先说概念。对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获…

[Kmeans 评价指标]标准化互信息NMI计算步骤及其Python实现

转载链接 转载过来的东西不造为什么不能全部显示,带来理解上的问题请转到上面链接查看原博文。 卓越是一个持续的过程而不是一个偶然事件. 标准化互信息NMI计算步骤及其Python实现 本文介绍其计算步骤和代码实现 假设对于17个样本点(v1,v2,...,v17)(v1,v2,...,v17)…

[论文笔记]Graph Embedding Techniques, Applications, and Performance: A Survey

这篇论文列举了目前graph embedding算法,将其分为“因式分解”、“随机游走”、“深度学习”三类,在不同的任务上评估其效果,最后提了点发展方向 前言定义算法分类研究现状基于因式分解的方法局部线性嵌入(LLE,Locally Linear Embedding)拉普…

无法定位程序输入点_glutInitWithExit于动态链接库glut32.dll

这几天在捣腾CUDA,用vs2012跑那个经典的julia例程的时候出了问题。 问题如题。 找了很多方法……最后自己误打误撞成功了。 步骤就是: 1)从网上下载glut的包包。里面应该会含有一个.h一个.dll和一个.lib 如果你是64位系统,把.dll放到c:/windows/sysWOW64…

Java集合-BlockingQueue【阻塞队列】

介绍 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景&…

[Python] TypeError: 'set' object is not callable”解决方案

Python set set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。 注:set中无index 今天读取两个文件合并,并去重。文件格式如下: 下面程序在29行报错’se…