java中的volatile关键字是什么作用

如题所述

第1个回答  2017-10-13
volatile 2个使用场景:
1.可见性:Java提供了volatile关键字来保证可见性。
当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。
另外,通过synchronized和Lock也能够保证可见性,synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。
先看一段代码,假如线程1先执行,线程2后执行:
?//线程1
boolean stop = false;
while(!stop){
doSomething();
}
//线程2
stop = true;

这段代码是很典型的一段代码,很多人在中断线程时可能都会采用这种标记办法。但是事实上,这段代码会完全运行正确么?即一定会将线程中断么?不一定,也许在大多数时候,这个代码能够把线程中断,但是也有可能会导致无法中断线程(虽然这个可能性很小,但是只要一旦发生这种情况就会造成死循环了)。
下面解释一下这段代码为何有可能导致无法中断线程。在前面已经解释过,每个线程在运行过程中都有自己的工作内存,那么线程1在运行的时候,会将stop变量的值拷贝一份放在自己的工作内存当中。
那么当线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,那么线程1由于不知道线程2对stop变量的更改,因此还会一直循环下去。
但是用volatile修饰之后就变得不一样了:
第一:使用volatile关键字会强制将修改的值立即写入主存;
第二:使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效);
第三:由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1再次读取变量stop的值时会去主存读取。
那么在线程2修改stop值时(当然这里包括2个操作,修改线程2工作内存中的值,然后将修改后的值写入内存),会使得线程1的工作内存中缓存变量stop的缓存行无效,然后线程1读取时,发现自己的缓存行无效,它会等待缓存行对应的主存地址被更新之后,然后去对应的主存读取最新的值。
那么线程1读取到的就是最新的正确的值。
2.保证有序性
volatile boolean inited = false;
//线程1:
context = loadContext();
inited = true;
//线程2:
while(!inited ){
sleep()
}
doSomethingwithconfig(context);

确保context已经初始化完成。
3.double check
?class Singleton{
private volatile static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}本回答被提问者采纳

Java中volatile关键字有什么作用?
Java中的volatile关键字主要用于弱同步,确保变量的实时更新并避免数据竞争。其核心特性包括变量可见性和禁止指令重排序。当一个线程修改volatile变量时,其他线程能够立即看到更新的值,实现数据同步。同时,volatile避免了CPU缓存中的指令重排序,避免了并发时可能出现的不一致性问题,尤其是在多处理器环境下,...

volatile可以保证同步性吗
volatile是一个Java关键字,用于确保变量的可见性以及禁止CPU缓存和编译器优化。当一个变量被声明为volatile后,它意味着这个变量在任何时刻都可能被其他线程修改,因此,任何对volatile变量的读写操作都会直接反映到硬件级别,这就保证了线程间的同步性。此外,由于volatile的写入操作是立即生效的,因此它可以...

Java干货 | Java中Volatile关键字的作用
Volatile关键字在Java中扮演的关键角色在于处理并发编程中多线程访问共享变量时的数据一致性问题。它告诉编译器这个变量是易变的,需要特殊对待。当变量被定义为Volatile类型时,它会强制所有对它的操作都必须从主内存中读取和写入,而非使用线程的缓存拷贝,从而确保了线程间的数据一致性和可见性。具体来说...

volatile关键字的作用
volatile在Java并发编程中常用于保持内存可见性和防止指令重排序。内存可见性(MemoryVisibility):所有线程都能看到共享内存的最新状态。防止指令重排:在基于偏序关系的Happens-Before内存模型中,指令重排技术大大提高了程序执行效率,但同时也引入了一些问题。volatile保持内存可见性的特殊规则:read、load、use...

volatile关键字及其作用
volatile关键字提供内存屏障的方式来防止指令被重排,编译器在生成字节码文件时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。JVM内存屏障插入策略:每个volatile写操作的前面插入一个StoreStore屏障;在每个volatile写操作的后面插入一个StoreLoad屏障;在每个volatile读操作的后面插入一个LoadLoad...

volatile 关键字,你真的理解吗?
volatile 关键字用于保证变量内存可见性和禁止指令重排序,主要涉及 Java 内存模型和并发编程。通过理解 volatile 的作用,可以解决多线程访问共享变量时的可见性问题。在多线程环境下,一个线程修改了共享变量的值后,其他线程需要立即读取到该值,才能保证程序的正确执行。volatile 保证了这一点,通过从主...

5.volatile是什么?怎么保证可见性?
volatile关键字的作用是告诉Java内存模型,当一个线程修改了共享变量后,这个修改会立即被更新到主内存中,而当其他线程读取共享变量时,它们会直接从主内存中读取。这样,多个线程可以同步看到相同的变量值,从而保证了可见性。除了可见性,volatile还提供了一定的有序性。在Java内存模型中,为了提高性能,...

volatile关键字的作用以及原理
Volatile关键字在Java中扮演着关键角色,它与内存模型紧密相关。首先,理解Java内存模型很重要,它规定变量存储在主内存中,线程工作内存负责处理。当线程访问共享变量时,会同步更新到主内存以确保可见性。然而,如果多个线程同时处理共享变量,Cache的存在可能导致内存可见性问题,这正是volatile解决的第一个...

Java并发性:了解“Volatile”关键字
volatile是一个用于字段的关键字,它保证了当一个线程向该字段写入值时,写入的值对随后读取该字段的任何线程“立即可用”。这个特性解决了多线程环境下共享数据的可见性问题,确保了线程间的同步。在多线程编程中,正确同步共享状态的访问至关重要。volatile提供了一种轻量级的同步机制,它不依赖于传统的...

volatile、ThreadLocal 的使用场景和原理是什么?
volatile 和 ThreadLocal 都是 Java 中的关键字,用于解决多线程并发问题。volatile 可以保证变量的可见性,即一个线程修改了 volatile 变量的值,其他线程可以立即看到修改后的值。但是 volatile 不能保证原子性,即多个线程同时访问同一个 volatile 变量时可能会出现数据不一致的情况。ThreadLocal 是 Java...

相似回答