这个可能是最好的对比volatile和synchronized作用的文章了。volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符。所以我们使用这两种关键字来指定三种简单的存取变量的方式。

int i1;                       int geti1() {return i1;}

volatile int i2;                       int geti2() {return i2;}

int i3;          synchronized int geti3() {return i3;}

geti1()在当前线程中立即获取在i1变量中的值。线程可以获得变量的本地拷贝,而所获得的变量的值并不一定与其他线程所获得的值相同。特别是,如果其他的线程修改了i1的值,那么当前线程获得的i1的值可能与修改后的值有所差别。实际上,Java有一种主内存的机制,使用一个主内存来保存变量当前的正确的值。线程将变量的值拷贝到自己独立的内存中,而这些线程的内存拷贝可能与主内存中的值不同。所以实际当中可能发生这样的情况,在主内存中i1的值为1,线程1和线程2都更改了i1,但是却没把更新的值传回给主内存或其他线程中,那么可能在线程1中i1的值为2,线程2中i1的值却为3。

另一方面,geti2()可以有效的从主内存中获取i2的值。一个volatile类型的变量不允许线程从主内存中将变量的值拷贝到自己的存储空间。因此,一个声明为volatile类型的变量将在所有的线程中同步的获得数据,不论你在任何线程中更改了变量,其他的线程将立即得到同样的结果。由于线程存取或更改自己的数据拷贝有更高的效率,所以volatile类型变量在性能上有所消耗。

那么如果volatile变量已经可以使数据在线程间同步,那么synchronizes用来干什么呢?两者有两方面的不同。首先,synchronized获取和释放由监听器控制的锁,如果两个线程都使用一个监听器(即相同对象锁),那么监听器可以强制在一个时刻只有一个线程能处理代码块,这是最一般的同步。另外,synchronized还能使内存同步。在实际当中,synchronized使得所有的线程内存与主内存相同步。所以geti3()的执行过程如下:

1.    线程从监听器获取对象的锁。(这里假设监听器非锁,否则线程只有等到监听器解锁才能获取对象锁)

2.    线程内存更新所有的变量,也就是说他将读取主内存中的变量使自己的变量保证有效。(JVM会使用一个“脏”标志来最优化过程,使得仅仅具有“脏”标志变量被更新。详细的情况查询JAVA规范的17.9)

3.    代码块被执行(在这个例子中,设置返回值为刚刚从主内存重置的i3当前的值。)

4.    任何变量的变更将被写回到主内存中。但是这个例子中geti3()没有什么变化。

5.    线程释放对象的锁给监听器。

所以volatile只能在线程内存和主内存之间同步一个变量的值,而synchronized则同步在线程内存和主内存之间的所有变量的值,并且通过锁住和释放监听器来实现。显然,synchronized在性能上将比volatile更加有所消耗。

文章转自:http://blog.csdn.net/majorboy/article/details/475811

关于volatile和synchronized的更多相关文章

  1. Thread 学习记录 <1> -- volatile和synchronized

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

  2. volatile与synchronized的区别

    1.锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility). 互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一 ...

  3. 从JAVA看C#中volatile和synchronized关键字的作用

    最近一直在想C#中 volatile关键字到底是用来干什么的?查了很多.NET的文章都是说用volatile修饰的变量可以让多线程同时修改,这是什么鬼... 然后查到了下面这篇JAVA中关于volat ...

  4. Volatile和Synchronized对可见性和原子性的支持

    在学习并发编程的时候,遇见了volatile和synchronized关键字问题,volatile是可以保证可见性,但无法保证原子性,synchronized关键字由于其是加锁机制,肯定是可以保证原子 ...

  5. volatile 与 synchronized 区别

    在Java中,为了保证多线程读写数据时保证数据的一致性,可以采用两种方式: 同步 如用synchronized关键字,或者使用锁对象. volatile 使用volatile关键字用一句话概括vola ...

  6. 剑指Offer——线程同步volatile与synchronized详解

    (转)Java面试--线程同步volatile与synchronized详解 0. 前言 面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现 ...

  7. 并发编程之ThreadLocal、Volatile、synchronized、Atomic关键字扫盲

    前言 对于ThreadLocal.Volatile.synchronized.Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点.区别 ...

  8. java多线程中 volatile与synchronized的区别-阿里面试

    volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...

  9. volatile与synchronized有什么区别?

    下列说法正确的是()? A.我们直接调用Thread对象的run方法会报异常,所以我们应该使用start方法来开启一个线程 B.一个进程是一个独立的运行环境,可以被看做一个程序或者一个应用.而线程是在 ...

随机推荐

  1. MVC 5 + EF6 入门完整教程14 -- 动态生成面包屑导航

    上篇文章我们完成了 动态生成多级菜单 这个实用组件. 本篇文章我们要开发另一个实用组件:面包屑导航. 面包屑导航(BreadcrumbNavigation)这个概念来自童话故事"汉赛尔和格莱 ...

  2. 查询自己电脑的IP

    1.怎样查询电脑的IP 1)运用dos命令 在运行窗体上输入cmd,进入dos命令窗体,输出ipconfig/all命令,找到自己的IP地址 上面所圈出的就是本机IP地址 2) 进入“网络和共享中心” ...

  3. flask环境开发搭建

    http://blog.csdn.net/chen_jint/article/details/50550636 ========== 因为笔者开发环境是win7pro,那么就以win7pro为例. p ...

  4. Titanium开发环境搭建第一个坑

    操作系统: Ubuntu 12.04 LTS AMD64 在Titanium Studio中,装Titanium CLI怎么都不能成功,到了一个进度,发现卡在那里,硬盘一直狂闪,发现在Studio的文 ...

  5. Struts2中 Result类型配置详解

    一个result代表了一个可能的输出.当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出.在com.opensymphony.xwor ...

  6. SQL Server性能影响的重要结论

    第一次访问数据会比接下来的访问慢的多,因为它要从磁盘读取数据然后写入到缓冲区: 聚合查询(sum,count等)以及其他要扫描大部分表或索引的查询需要大量的缓冲,而且如果它导致SQL Server从缓 ...

  7. 通过一个小问题来学习SQL关联查询

    原话题: 是关于一个left join的,没有技术难度,但不想清楚不一定能回答出正确答案来: TabA表有三个字段Id,Col1,Col2 且里面有一条数据1,1,2 TabB表有两个字段Id,Col ...

  8. ajax跨子域请求的两种现代方法

    因为面向互联网的性质,我们公司的大部分系统都采用多子域的方式进行开发和部署,以达到松耦合和分布式的目的,因此子系统间的交互不可避免.虽然通过后台的rpc框架解决了大部分的交互问题,但有些情况下,前端直 ...

  9. jQuery Flickerplate 幻灯片

    Flickerplate 是个轻量级 jQuery 插件,大小仅为 12 kb.它允许用户点击鼠标然后转换内容,非常容易使用,响应式,支持触摸设备 在线实例 默认 圆点导航位置 动画方式 深色主题 H ...

  10. CSS3随内容自动伸缩的背景

    CSS3给我们带来一个非常实用的新属性:border-image,利用这个属性我们可以做出随着内容的增减自动伸缩的背景.废话不多说,看代码! HTML: <ol> <li>第一 ...