这个可能是最好的对比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更加有所消耗。
=============关于两者的区别===================
1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
3.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化
相关推荐
在Java中,为了保证多线程环境下数据的一致性和安全性,可以采用两种主要的方法:`synchronized`和`volatile`。 ##### 1. synchronized关键字 `synchronized`是一种基于锁的同步机制,它可以应用于方法或者代码块...
Java 中 volatile 和 synchronized 的区别与联系 Java 中的 volatile 和 synchronized 是两种不同的关键字,它们都是用来解决多线程编程中出现的问题,但是它们的作用机制和使用场景却不同。 volatile volatile ...
Java关键字volatile和synchronized作用和区别 Java关键字volatile和synchronized是Java语言中两个常用的关键字,它们都是用来解决多线程编程中的同步问题的,但它们的作用和用法却有所不同。 volatile关键字是变量...
volatile与synchronized的区别,锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)
在Java多线程编程中,volatile和synchronized是两种重要的同步机制,用于处理并发环境下的数据一致性问题。这里我们将深入探讨这两个关键字的用法、作用以及它们之间的区别。 首先,volatile关键字。volatile确保了...
3. 有序性:Java语言提供了volatile 和synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重排序”的语义,synchronized是由“一个变量在同一个时刻只允许一条线程对其进行...
8. volatile 和 synchronized 的区别:volatile 更轻量级,不会引起线程上下文的切换和调度,而 synchronized 会。volatile 只能保证单个变量的原子性和可见性,而 synchronized 可以保证整个代码块的原子性。 9. ...
Java 面试题总结 ...Volatile 和 Synchronized 是 Java 中的两种同步机制。Volatile 是一种轻量级的同步机制,用于实现线程间的数据共享。Synchronized 是一种重量级的同步机制,用于实现线程间的数据共享和同步。
还涉及到线程安全的关键字volatile和synchronized的区别及其使用场景。 适合人群:对Java多线程编程有一定兴趣的技术爱好者和程序员。 使用场景及目标:①帮助企业级开发人员更好地理解Java集合类的功能与内部运作;...
JMM规定了线程如何看到其他线程对共享变量的修改,并规定了必要的同步策略,如volatile关键字和synchronized块,以保证内存可见性和有序性。 2. JMM抽象地描述了程序运行时的数据流向,包括工作内存(包含CPU缓存和...
Java内存模型通过synchronized和volatile以及CAS(Compare and Swap)操作来保证原子性。 5. 有序性:在单线程环境中,程序的执行顺序与代码的书写顺序一致。但在多线程环境中,为了优化性能,JVM可能会重新排序...
Java通过synchronized和volatile关键字提供了一套高级并发控制机制,而处理器通过原子指令来保证基本的并发操作。比如x86架构的lock前缀指令,可以保证在执行操作时其他处理器不能访问对应的内存地址,从而实现原子...
Java 内存模型(JMM)是Java编程中用于处理多线程环境下数据一致性问题的重要概念...开发者需要理解并利用好JMM提供的机制,如volatile和synchronized,来解决多线程环境中的并发问题,以编写出高效且可靠的并发程序。
Java提供了volatile和synchronized来保证线程间的有序性。volatile关键字禁止指令重排序,而synchronized保证了同一时间只有一个线程能执行特定的代码块,从而确保了执行的顺序。 此外,Java内存模型中有一个“先行...
它规定了volatile变量、synchronized块和final字段的语义,以确保内存可见性和线程间的同步。 volatile关键字是Java中用于线程间通信的关键特性。它保证了变量的可见性,即当一个线程修改了volatile变量后,其他...
9. ** volatile和synchronized的区别**:volatile仅保证可见性和有序性,不保证原子性;而synchronized则提供锁机制,保证了原子性、可见性和有序性。 深入理解Java内存模型,可以帮助开发者避免并发编程中出现的...
在并发编程中,volatile和synchronized常常结合使用,volatile保证了变量的可见性和有序性,而synchronized负责控制并发访问。 5. 面试常考编程题---线程交替打印 线程交替打印是指在多线程环境中,多个线程按照...
8. **编程实践**:JSR133提供了一些最佳实践,如避免使用不安全的并发工具,正确使用volatile和synchronized等,帮助开发者编写出高效且线程安全的代码。 "JSR133中文版1.pdf"文件很可能是这份规范的完整中文翻译,...
Java提供了多种并发工具和机制,如synchronized、volatile、java.util.concurrent包下的各种并发容器,以及ReentrantLock、Semaphore等,帮助开发者实现线程安全的代码。在编写多线程代码时,应该根据具体需求选择...
例如,合理使用volatile关键字可以减少不必要的缓存刷新,而明智地运用synchronized可以防止数据不一致,提高程序的正确性和可靠性。因此,深入学习并发编程的关键概念以及它们在现代计算机硬件上的实现,是成为高效...