轻量级同步机制volatile

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

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

介绍

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

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

在这里插入图片描述

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

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

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

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值