首页 > 试题广场 >

说说volatile的用法及原理

[问答题]
说说volatile的用法及原理
1.修饰被不同线程访问和修改的变量 2.被其修饰的变量,系统每次用到它时都是直接从对应的内存中提取,而不会利用缓存(如寄存器),所有线程在任何时候所看到变量的值都是相同的 3.volatile不能保证操作的原子性,因此不能代替synchronized 4.能不使用就尽量不要使用
发表于 2022-04-06 21:32:48 回复(4)

1、volatile是一个Java的关键字,用来解决内存可见性问题的。

2、当多个线程操作共享变量时,会存在数据不一致的问题。因为在Java内存模型中,有工作内存和主内存,每个线程都有自己的工作内存,里边存储变量的副本,当对一个普通变量进行写操作时,不会立即同步到主内存,因此其他线程不能立即看到最新的值,这就是内存可见性问题。

3、通过volatile关键字修饰的变量可以解决这个问题,JVM底层是通过内存屏障来实现,当对一个变量进行读取时,插入读屏障,表示先从主内存读取,当对一个变量进行写入后,插入写屏障,表示立即同步到主内存,这样就解决了可见性问题,保证了数据一致性,对应于硬件层面,看到资料说是Intel提供了缓存一致性协议MESI,对共享变量写入时,发出通知让其他CPU核心缓存行失效,早期的CPU是通过对总线加锁的方式实现。

4、但volatile不能解决原子性问题,因为每个线程都有工作内存,各自线程计算完后同步到主内存会存在覆盖的问题。

5、volatile的使用场景一般用在于一个线程读,另一个线程写的情况下,例如标志位这类,同时读写一个volatile的场景不适合,因为会出现原子性问题。

发表于 2022-06-25 09:13:20 回复(0)
1.保证可见性,当一个线程修改了呗volatile修饰的变量时,其他线程是可以看到的。 2.禁止指令重排序。
发表于 2022-04-28 14:36:45 回复(0)
volatile主要用于修饰多线程中的共享变量,它可以保证变量的可见性和有序性,不能保证原子性。可见性是指在多线程环境中若某个线程修改了该变量,那么其他线程就能察觉到变量的修改。可见性主要是通过在内存模型中修改了某值则将它同步会主内存,在读取前从主内存刷新该变量值来实现的。有序性是指在某个线程中对该变量的操作顺序时透明的不会改变的。在java中由于寄存器和内存处理速度存在巨大差异所以java为了提升运行速度会将编译好的代码进行一定程度的重排但不影响其在独立线程环境下的运行结果,但是在多线程环境中有可能出错。volatile可以避免这种指令重排实现其在多线程的顺序一致的效果。
发表于 2022-05-21 13:51:50 回复(0)
volatile关键字是比synchronized关键字更加轻量化。只能保证单共享变量的线程安全问题。1.保证变量的可见性和有序性。可见性:当一个共享变量被修改时,其他线程可以知道。有序性:通过禁止指令重排实现。
发表于 2022-06-15 19:33:35 回复(0)
"1、volatile是Java并发编程中比较重要的一个关键字,用来修饰变量,无法修饰方法以及代码块;其用法简单,只需在声明一个可能被多线程同时访问的变量时,使用volatile修饰即可 2、volatile原理:为了提高处理器的执行速度,在处理器和内存之间增加了多级缓存来提升,因而存在缓存不一致的问题。所以为解决该问题,volatile遵循缓存一致性协议,进而保证了volatile在并发编程中,其值在多个缓存中是可见的。 缓存一致性协议:每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读取到处理器缓存里。 3、三个特性:可见性、有序性、原子性(无法保证) 可见性:可见性是指当多个线程访问同一个变量时,一个线程修改了该变量值,其他线程能够立即看到并修改(正是遵循了缓存一致性) 有序性(禁止指令重排序):有序性即为程序执行的顺序按照代码的先后顺序执行(内存屏障保证有序性) 原子性:原子性是指一个操作时不可中断的,要全部执行完成,要不就都不执行。"
发表于 2022-09-08 16:16:51 回复(0)
可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入,解决多核CPU缓存可见性问题 有序性:采用内存屏障来实现的,就是在编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序 原子性:对单个volatile变量的读写具有原子性,对“volatile变量++”这种复合操作则不具有原子性,但是volatile写与锁的释放有相同的内存语义。 volatile只能保证单个变量读写的原子性,而锁则可以保证对整个临界区的代码执行具有原子性
发表于 2022-05-10 22:36:17 回复(0)
禁止指令重排序标记下:volatile的底层是采用内存屏障来实现的,就是在编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
发表于 2022-05-04 22:07:51 回复(0)
volatile关键字修饰的变量可以保证可见性,有序性,但不能保证原子性。 可见性:一个线程对共享变量进行修改,另一个线程能看见最新结果。(volatile修饰的关键字不会经过JIT优化保证可见性) 有序性:代码按顺序执行 原子性:一个线程内多行代码以一个整体执行,期间不能有其他线程的代码插队 可以用synchronized来同步代码块解决原子性问题
发表于 2023-02-23 21:46:11 回复(0)
可以用来修饰多线程下的共享变量。保证了变量的可见性和原子性。需要注意的是,volatile的原子性只针对单个变量,复合操作不能保证原子性,这也是和synchronized的区别。volatile修饰变量后,在写操作时,会将值从本地内存刷新到主内存中;在读操作时,会强制无效化本地内存,迫使线程从主内存上读取值。volatile底层是通过内存屏障来实现的,通过在指令序列中插入内存屏障来实现禁止指令重排的效果。
发表于 2022-07-30 12:28:41 回复(0)
volatile主要用于修饰多线程中的共享变量,它可以保证变量的可见性和有序性,但不能保证原子性。可见性是指在多线程环境中,若某个线程修改了该变量,那么其他线程就能察觉到变量的修改,可见性主要是通过在内存模型中修改了某值则将它同步到主内存,在读取前从主内存刷新该变量值来实现的。有序性是指在某个线程中对变量的操作顺序是透明的不会改变的。在Java中由于寄存器和内存处理器速度存在巨大差异,所以Java为了提升运行速度会将编译好的代码进行一定程序的重排但不影响其在独立线程环境下的运行结果,但是在多线程环境中有可能出错。volatile可以避免这种指令重排实现其在多线程的顺序一致的效果。
发表于 2022-07-19 10:24:07 回复(0)
volatile最大的功能就是为我们的程序提供了可见性保证。
发表于 2022-07-12 21:08:30 回复(0)
用法:用于修饰共享变量保证可见性,保证有且只能一个线程写,可以多个线程读的操作。原理:用内存屏障实现的,分为读屏障和写屏障,写屏障会在写指令之后加入,读屏障会在读指令之前加入,可以保证可见性和有序性(防止指令重排),不能保证原子性。保证可见性:在写屏障之前,会将共享变量的改动同步到主存中,然后在读屏障之后,获取到主存中的值。有序性:不会将写屏障之前的代码排序到写屏障之后,不会将读屏障之后的代码排序到读屏障之前。
编辑于 2023-02-04 12:08:40 回复(0)
volatile是一个轻量级synchronize锁,它能保证多处理器开发过程共享变量的可见性,当一个线程修改了被volatile修饰的变量时,对于其他线程是可见的。它的底层是采用内存屏障来实现的,就是在编译器生成字节码文件时,会在指令序列中插入内存屏障来禁止指令重排序。
编辑于 2022-10-07 21:06:19 回复(0)
可见性、禁止指令生排序、64位基本数据类型的原子性
发表于 2024-05-28 16:05:38 回复(0)
volatile是一种常用的线程安全方法。该关键字一般用来修饰变量,主要有两个作用:建议编译器不要进行指令重排序;多线程/处理器的情况下,指令变量的更新会立即刷新到内存之中。保证了同步变量的可见性。但是volatile实际上并不能保证操作的原子性
发表于 2024-05-25 15:31:10 回复(0)
1.volatile修饰被不同线程访问和修改的变量 2.volatile 的原理主要基于 Java 内存模型(Java Memory Model, JMM)和内存屏障(Memory Barrier),是轻量级的同步机制,它实现了变量的可见性、防止指令重排序,保证了单个变量读写的线程安全,
发表于 2024-05-24 00:10:16 回复(0)
volatile修饰变量,可以保证变量的可见性和防止指令重排序,不能保证变量的原子性 在当今的java内存环境,线程可以在本地内存(直接内存)保存变量,而不会直接在主存中读写,当一个线程修改主存中的变量,而另一个线程访问原变量在寄存器中变量值的拷贝,数据不一致,可以使用volatile修饰变量,指示虚拟机变量不稳定,从主存中读写
编辑于 2024-05-15 21:08:30 回复(0)
修饰被不同线程访问的变量。
编辑于 2024-04-03 10:43:47 回复(0)
变量加上volatile 保证变量的可见性,禁止指令重排。一旦变量被修改立即加载到内存中,不能保证原子性。
编辑于 2024-04-02 16:51:51 回复(0)