synchronized与volatile的区别,它们的作用及原理?

说到两者的区别,先要了解锁提供的两种特性:互斥(mutual exclusion) 和可见性(visibility)

互斥:即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。

  可见性:要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享         变量可能是修改前的值或不一致的值,这将引发许多严重问题。(竞态条件)


java多线程中的原子性、可见性、有序性
     (1)、原子性:是指线程的多个操作是一个整体,不能被分割,要么就不执行,要么就全部执行完,中间不能被打断。
     (2)、可见性:是指线程之间的可见性,就是一个线程修改后的结果,其他的线程能够立马知道。
     (3)、有序性:为了提高执行效率,java中的编译器和处理器可以对指令进行重新排序,重新排序会影响多线程并发的正确性,有序性就是要保证不进行重新排序(保证线程操作的执行顺序)。


接着要了解两者的作用及原理:

volatile关键字的作用:
其实volatile关键字的作用就是保证了可见性和有序性(不保证原子性),如果一个共享变量被volatile关键字修饰,那么如果一个线程修改了这个共享变量后,其他线程是立马可知的。为什么是这样的呢?比如,线程A修改了自己的共享变量副本,这时如果该共享变量没有被volatile修饰,那么本次修改不一定会马上将修改结果刷新到主存中,如果此时B去主存中读取共享变量的值,那么这个值就是没有被A修改之前的值。如果该共享变量被volatile修饰了,那么本次修改结果会强制立刻刷新到主存中,如果此时B去主存中读取共享变量的值,那么这个值就是被A修改之后的值了。
volatile能禁止指令重新排序,在指令重排序优化时,在volatile变量之前的指令不能在volatile之后执行,在volatile之后的指令也不能在volatile之前执行,所以它保证了有序性。

synchronized关键字的作用
synchronized提供了同步锁的概念,被synchronized修饰的代码段可以防止被多个线程同时执行,必须一个线程把synchronized修饰的代码段都执行完毕了,其他的线程才能开始执行这段代码。
因为synchronized保证了在同一时刻,只能有一个线程执行同步代码块,所以执行同步代码块的时候相当于是单线程操作了,那么线程的可见性、原子性、有序性(线程之间的执行顺序)它都能保证了。

看到这里就知道了一些基本区别,volatile保证了可见性和有序性(不保证原子性)但是synchronized保证了可见性和有序性的同时还保证了原子性。

接着就是它们具体的区别:

1)volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。

2)volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。

   3)volatile仅能实现变量修改的可见性,而synchronized则可以保证变量修改的可见性和原子性。《Java编程思想》上说,定义long或double时,如果使用volatile关键字(简单的赋值与返回操作),就会获得原子性。(常规状态下,这两个变量由于其长度,其操作不是原子的)

   4)volatile不会造成线程阻塞,synchronized会造成线程阻塞。

   5)使用volatile而不是synchronized的唯一安全情况是类中只有一个可变的域。

简明扼要来说就是一下三点:

(1)、volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。
(2)、volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。
(3)、volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。

synchronized与volatile的区别及各自的作用、原理(学习记录)的更多相关文章

  1. synchronized和lock以及synchronized和volatile的区别

    synchronized和volatile区别synochronizd和volatile关键字区别: 1. volatile关键字解决的是变量在多个线程之间的可见性:而sychronized关键字解决 ...

  2. 4个点说清楚Java中synchronized和volatile的区别

    作者 : Hollis 回顾一下两个关键字:synchronized和volatile 1.Java语言为了解决并发编程中存在的原子性.可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如sy ...

  3. java synchronized与volatile的区别

    java线程同步有两个特性,一个是可见性,一个是有序性.在解释这两个概念之前,先说下两个重要的概念,主内存(main memory)和工作内存(working memory),线 程之间数据的交互不是 ...

  4. synchronized和volatile的区别

    但是volatile不适合做计数器使用,即使他具有可见性,但是它不具有原子性.不能保证数据的一致性. 但是volatile适合哪种场景呢? 比较适合做一些标示.比如说两个线程,线程B必须得等线程A执行 ...

  5. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  6. 【java并发编程艺术学习】(四)第二章 java并发机制的底层实现原理 学习记录(二) synchronized

    章节介绍 本章节主要学习 Java SE 1.6 中为了减少获得锁 和 释放锁 时带来的性能消耗 而引入的偏向锁 和 轻量级锁,以及锁的存储结构 和 升级过程. synchronized实现同步的基础 ...

  7. java并发编程(2) --Synchronized与Volatile区别

    Synchronized 在多线程并发中synchronized一直是元老级别的角色.利用synchronized来实现同步具体有一下三种表现形式: 对于普通的同步方法,锁是当前实例对象. 对于静态同 ...

  8. synchronized和volatile的使用方法以及区别

    先看看下面的例子: public class ThreadTest { public static void main(String[] args) { final Counter counter = ...

  9. synchronized与Lock、volatile的区别

    synchronized与volatile的区别 volatile是线程同步的轻量级实现,因此volatile性能好于synchronized voaltile修饰变量,synchronized修饰方 ...

随机推荐

  1. CROI R1

    $CROI$ $R1$ 今天参加了一场比赛,什么比赛呢?CROI. CROI是什么呢? $Challestend$ $Rehtorbegnaro$ $OI$.总的来说就是我们机房的一些神仙出的题啦. ...

  2. [CQOI2018]破解D-H协议

    嘟嘟嘟 这不就是个bsgs板儿嘛. 顺便就复习了一下bsgs和哈希表. 头一次觉得我的博客这么好用,一下就懂了:数论学习笔记之高次不定方程 这里再补充几点: 1.关于这一段代码: int S = sq ...

  3. 【angularjs】使用angular搭建项目,实现隔行换色

    描叙:使用ng-class实现每隔3行换色 代码: <!DOCTYPE html> <html ng-app="myApp"> <head> & ...

  4. java 定时任务多线程处理

    @Configuration@EnableSchedulingpublic class ScheduleConfig implements SchedulingConfigurer, AsyncCon ...

  5. wxWidgets与其它GUI工具库比较

    WxWidgets Compared To Other Toolkits   Some general notes: wxWidgets not only works for C++, but als ...

  6. 移动端h5页面编写样式重置

    @charset "UTF-8"; /* stylelint-enable */ /* 重置样式 */ * { -webkit-tap-highlight-color: trans ...

  7. 在.NET中调用Java的类

    .NET不能直接调用Java的类,但IKVM.NET解决了这个问题. IKVM.NET提供了两种方式调用java的类: ①把生成的jar包放置在程序根目录,然后通过创建URL实例的方式去调用类中的方法 ...

  8. Java关键字(四)——final

    对于Java中的 final 关键字,我们首先可以从字面意思上去理解,百度翻译显示如下: 也就是说 final 英文意思表示是最后的,不可更改的.那么对应在 Java 中也是表达这样的意思,可以用 f ...

  9. flex布局,最后一行左对齐

    拥抱flex 网上查找资料解决办法都是操作数据,个人感觉css问题还是用css来解决(当然问题不同,解决方案不同,这里只是针对某个问题的解决方法,不能解决所有问题,大家视情况而定,如果还是不行欢迎沟通 ...

  10. 响应式卡片抽奖插件 CardShow

    GitHub: https://github.com/nzbin/CardShow/ Demo: https://nzbin.github.io/CardShow/ 前言 这个小项目(卡片秀)是一个卡 ...