Java中关键字volatile 和 synchronized 的作用和区别

volatile是变量修饰符,而synchronized则是作用于一段代码或方法;如下三句get代码:

1 int i1;
2 int geti1() {return i1;}
3
4 volatile int i2;
5 int geti2() {return i2;}
6
7 int i3;
8 synchronized int geti3() {return i3;}

geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。

geti2() 得到的是main memory的i2数值。一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中。换句话说,一个变量经过volatile修饰后在所有线程中必须是同步的,任何线程中改变了它的值,所有其他线程立即获得了相同的值。所以,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。

geti3()方法被synchronized修饰,用synchronized来修饰一个方法或者一个贷款的时候,能够保证在同一时刻最多只有一个线程执行该段代码。既然volatile关键字已经实现了线程间数据同步,又要synchronized干嘛呢?当两个并发线程访问同一个对象object中的这个synchronized(this)同步贷款时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块才能执行该代码块。然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时候,其他线程对object中所有其他synchronized(this)同步代码块的访问将被阻塞。当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁,结果,其他线程对该对象所有同步代码部分的访问都被暂时阻塞。

总结一下区别:

一,volatile是变量修饰符,而synchronized则作用于一段代码或者方法。

二,volatile只是在线程内存和main memory(主内存)间同步某个变量的值;而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。

时间: 2024-10-15 05:41:14

Java中关键字volatile 和 synchronized 的作用和区别的相关文章

Java中关键字continue、break和return的区别

Java中关键字continue.break和return的区别: continue:跳出本次循环继续下一次循环 break:   跳出循环体,继续执行循环外的函数体 return:   跳出整个函数体,函数体后面的部分不再执行 有代码才有真相: [java] view plain copy <span style="font-family:SimSun;font-size:14px;"><span style="font-family:SimSun;fon

【转】java中关键字volatile的作用

在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器).为了性能,一个线程会在自己的memory中保持要访问的变量的副本.这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory中的值,或者main memory中的值不一致的情况. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来避免这种情况

java中关键字volatile的作用

用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来避免这种情况的.volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A) =========================分割线1================================= 版权声明 :转载时请以超链接形式标明文章原始出处和作者信息及本

转!!java中关键字volatile的作用

用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来避免这种情况的.volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A) =========================分割线1================================= 版权声明 :转载时请以超链接形式标明文章原始出处和作者信息及本

java中关键字volatile

1.用在多线程同步变量时, 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来避免这种情况的.volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A) 2.在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器).为了性能,一个线程会在自己的memory中保持要访问的变量的副本.这样就会出现同一个

Java中的Volatile和synchronized的区别

原文地址:https://www.cnblogs.com/MJyc/p/10374602.html

一定要你明白Java中的volatile

今天Tony来和大家聊聊Java中关键字volatile. 字节码 首先volatile int a = 3;和int a = 3;,加不加volatile关键字,最终生成的字节码都一样的.有兴趣的同学可以试试看看字节码是否一样. 英文解释 Adding volatile to the field does not change Java bytecode that reads or writes the field. It only changes the interpretation of

理解java中的volatile关键字

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了 实现代码线程的安全性.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分. volatile 写和读的内存语义: 线程 A 写一个 volatile 变量,实质上是线程 A

Java并发关键字Volatile 详解

Java并发关键字Volatile 详解 问题引出: 1.Volatile是什么? 2.Volatile有哪些特性? 3.Volatile每个特性的底层实现原理是什么? 相关内容补充: 缓存一致性协议:MESI ? 由于计算机储存设备(硬盘等)的读写速度和CPU的计算速度有着几个数量级别的差距,为了不让CPU停下来等待读写,在CPU和存储设备之间加了高速缓存,每个CPU都有自己的高速缓存,而且他们共享同一个主内存区域,当他们都要同步到主内存时,如果每个CPU缓存里的数据都不一样,这时应该以哪个数