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

程之间数据的交互不是直接传递,而是通过共享变量来实现的。对象的创建是在主内存中,而线程用到该对象时,是先拷贝一个该对象的副本放到线程的工作内存中,然后对该副

本对象进行操作,完成后在刷新到主内存中。而这个操作过程中的几个步骤不是原子性的,这样就有可能造成读脏数据等问题。关于这个问题,网上有这段解释:

根据java语言规范的规定,线程的工作内存和主存间的数据交换是松耦合的,什么时候需要刷新工作内存或者什么时候更新主存的内容,可以由具体的虚拟机实现自行决定。由于

JVM可以对特征代码进行调优,也就改变了某些运行步骤的次序的颠倒,那么每次线程调用变量时是直接取自己的工作存储器中的值还是先从主存储器复制再取是没有保证的,任

何一种情况都可能发生。同样的,线程改变变量的值之后,是否马上写回到主存储器上也是不可保证的,也许马上写,也许过一段时间再写。那么,在多线程的应用场景下就会出

现问题了,多个线程同时访问同一个代码块,很有可能某个线程已经改变了某变量的值,当然现在的改变仅仅是局限于工作内存中的改变,此时JVM并不能保证将改变后的值立马

写到主内存中去,也就意味着有可能其他线程不能立马得到改变后的值,依然在旧的变量上进行各种操作和运算,最终导致不可预料的结果。

现在来解释下可见性和有序性。可见性是指对于一个共享变量,当一个线程改变了其值时,这个变化应该对另一个线程可见,即另一个线程读到的值就是改变后的值。而有序

性是指对于共享变量的访问,当有一个线程在访问该变量时,其他线程必须等到该线程访问结束后才能去访问。这样就保证了同一时刻只有一个线程在访问,修改共享变量。

synchronized可以修饰方法,代码块,实际上都是获取了一个对象作为锁,在线程进入synchronized块之前,会把工作存内存中的所有内容映射到主内存上,然后把工作内存

清空再从主存储器上拷贝最新的值。而在线程退出synchronized块时,同样会把工作内存中的值映射到主内存,不过此时并不会清空工作内存。这样一来就可以强制其按照上面的

顺序运行,以保证线程在执行完代码块后,工作内存中的值和主内存中的值是一致的,保证了数据的可见性,并且当有其他线程试图访问synchronized的方法时,也必须要获取锁

对象,但是由于锁被当前线程所占用,只能等待该线程释放锁对象,也就保证了有序性。

volatile修饰变量,只保证了可见性,没有保证有序性。当线程访问被volatile修饰的共享变量时,会直接从主存中读取,修改也是直接修改主存中的数据,这样,由于缺少拷贝

的过程,其他线程访问该共享变量时,肯定是修改后的数据,即保证了可见性。但是如果多个线程同时访问了该共享变量,并做了修改,这样就容易产生有序性问题。如:

count=100,线程a 读取后加10, 线程b读取后-10,a,b可能同时读到了100,做修改后可能count值为90或110,这样就出现了脏数据的问题。故对volatile的使用,需要谨慎。

java synchronized与volatile的区别的更多相关文章

  1. synchronized与volatile的区别及各自的作用、原理(学习记录)

    synchronized与volatile的区别,它们的作用及原理? 说到两者的区别,先要了解锁提供的两种特性:互斥(mutual exclusion) 和可见性(visibility). 互斥:即一 ...

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

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

  3. Java synchronized和 Lock 的区别与用法

    在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方.  ...

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

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

  5. java - synchronized与lock的区别

    synchronized与lock的区别 原始构成 synchronized是关键字属于JVM层面 monitorenter(底层是通过monitor对象来完成,其实wait/notify等对象也依赖 ...

  6. java synchronized(object/this)的 区别

    1.synchronized(object) package test.thread; import java.io.IOException; import org.junit.Test; /* * ...

  7. synchronized和volatile的区别

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

  8. 从Java synchronized和volatile说起

    请参看https://www.cnblogs.com/chengxiao/p/6528109.html这个链接,说的特别好

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

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

随机推荐

  1. usb host和usb device

    S3C2440的数据手册将USB功能分为两章--usb host和usb device.具体什么意思呢? usb host: 微处理器作为usb主设备,可以挂接U盘之类的从属设备. usb devic ...

  2. LDR伪指令与ADR伪指令的区别

    测试代码 ldr r0, _start adr r0, _start ldr r0, =_start nop mov pc, lr _start: nop 设置代码的起始地址为 0x0c008000, ...

  3. 破解EXCEL2007的密码

    破解EXCEL2007的密码 xshzhao (斑竹)顶楼举报 我有一个EXCEL2007文件(后缀是XLSX),由于设置了打开密码.现在密码搞忘了,这个文件对我很重要. 我试过了Office Pas ...

  4. ACMer程序员智力拾遗

           浏览网页偶得,遂记录下来,每天进步一点点--        博客园真是个不错的平台,今天我让师姐也注册了--        学会分享吧,孩子们-- 一.编程中无穷大量的设置        ...

  5. 找到个好的讲PYTHON FILE IO的文档,收藏

    现在我感觉快入门了哈, 这两天,可以用PYTHON写一点自己想要实现的东东了. 但文件,IO,编码,邮件,始终有点续不完全. 这个文档,我看行.. http://www.dabeaz.com/pyth ...

  6. POJ 2075 Tangled in Cables 最小生成树

    简单的最小生成树,不过中间却弄了很久,究其原因,主要是第一次做生成树,很多细节不够熟练,find()函数的循环for判断条件是 pre[i]>=0,也就是遇到pre[i]==-1时停止,i就是并 ...

  7. WeakHashMap理解

    WeakHashMap实现了Map接口,是HashMap的一种实现,他使用弱引用作为内部数据的存储方案,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不够的时候,垃圾收集器会自动的清除 ...

  8. block的是发送信号的线程,又不是处理槽函数的线程

    请问UI线程给子线程发信号,应该用哪种连接方式? 如果子线程正在执行一个函数,我发射信号去执行子线程的另一个函数,那么此时子线程到底会执行什么呢? 用信号量做的同步.第一把信号槽的事件丢到线程的事件队 ...

  9. Realm for Android快速入门教程

    介绍 如果你关注安卓开发的最新趋势,你可能已经听说过Realm.Realm是一个可以替代SQLite以及ORMlibraries的轻量级数据库. 相比SQLite,Realm更快并且具有很多现代数据库 ...

  10. WebX配置文件、启动与响应流程

    ** 最近几天一直在看Spring的Ioc和AOP的源码介绍,还有Webx的使用.看Spring的源代码让人眼花缭乱,webx的配置文件也会让人感觉错综复杂无从下手.今天把之前看到的想到的webx相关 ...