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. HDU 1394 Minimum Inversion Number 线段树

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...

  2. [JavaScript] js 复制到剪切板

    zeroclipboard官网:https://github.com/zeroclipboard/ZeroClipboard 下载压缩包,得到两个“ZeroClipboard.js”和“ZeroCli ...

  3. bzoj 2746: [HEOI2012]旅行问题 AC自动机fail树

    2746: [HEOI2012]旅行问题 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 489  Solved: 174[Submit][Status ...

  4. BZOJ 1711: [Usaco2007 Open]Dingin吃饭

    Description 农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. ...

  5. BZOJ 1640: [Usaco2007 Nov]Best Cow Line 队列变换

    Description FJ打算带着他可爱的N (1 ≤ N ≤ 2,000)头奶牛去参加"年度最佳老农"的比赛.在比赛中,每个农夫把他的奶牛排成一列,然后准备经过评委检验. 比赛 ...

  6. Spring MVC注解冲突

    SpringMVC+MyBatis - 7 Spring自动扫描注解类的冲突问题 http://www.blogjava.net/crazycy/archive/2014/07/12/415738.h ...

  7. Linq 取差集 交集等

    string goodsList = context.Request.Form["goodsList"]; if (!string.IsNullOrEmpty(goodsList) ...

  8. 李洪强漫谈iOS开发[C语言-031]-逻辑短路

  9. Android 通过代码设置radiobutton不同方位图标的两种方法

    更换radiobutton中的图片在xml中很好设置,但对于初学者如何在代码中设置还是不容易找的.没法子,通过看原版api找到两个方法,setCompoundDrawables和setCompound ...

  10. Apache benchmark 压力测试工具

    ab 的全称是 ApacheBench , 是 Apache 附带的一个小工具 , 专门用于 HTTP Server 的 benchmark testing , 可以同时模拟多个并发请求. 安装apa ...