首页 > 试题广场 >

下列说法正确的是( )

[单选题]
下列说法正确的是( )
  • volatile,synchronized
    都可以修改变量,方法以及代码块
  • volatile,synchronized 在多线程中都会存在阻塞问题
  • volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性
  • volatile解决的是变量在多个线程之间的可见性、原子性,而sychroized解决的是多个线程之间访问资源的同步性
  • 关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且只能修改变量,而synchronized可以修饰方法,以及代码块。
  • 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞
  • volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步
  • 关键字volatile解决的下变量在多线程之间的可见性;而synchronized解决的是多线程之间资源同步问题
--<<Java多线程编程核心技术>>

发表于 2019-07-24 15:27:44 回复(13)

可见性:

可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。

可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。比如 volatile int a = 0;之后有一个操作 a++;这个变量a具有可见性,但是a++ 依然是一个非原子操作,也就是这个操作同样存在线程安全问题。

在 Java 中 volatile、synchronized 和 final 实现可见性。

原子性:

原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。java的concurrent包下提供了一些原子类,我们可以通过阅读API来了解这些原子类的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。

在 Java 中 synchronized 和在 lock、unlock 中操作保证原子性。

有序性:

Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重排序”的语义,synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行执行。

当一个变量定义为 volatile 之后,将具备两种特性:

1.保证此变量对所有的线程的可见性,这里的“可见性”,如本文开头所述,当一个线程修改了这个变量的值,volatile 保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。但普通变量做不到这点,普通变量的值在线程间传递均需要通过主内存(详见:Java内存模型)来完成。

2.禁止指令重排序优化。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障;(什么是指令重排序:是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理)。

volatile 性能:

volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。

摘自https://www.cnblogs.com/zhengbin/p/5654805.html
发表于 2019-07-12 15:07:25 回复(7)
volatile和synchronized的区别
  • volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  • volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、代码块和类级别的。
  • volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性。
  • volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  • volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。
  • volatile能保证数据的可见性,但不能完全保证数据的原子性(不能保证复合操作的原子性),synchronized即保证了数据的可见性,也保证了原子性。
发表于 2019-07-07 22:49:15 回复(7)

synchronized和volatile区别

摘自《Java多线程编程核心技术》

关于synchronized和volatile的比较:

  • 关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且只能修改变量,而synchronized可以修饰方法,以及代码块。
  • 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞
  • volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步
  • 关键字volatile解决的下变量在多线程之间的可见性;而synchronized解决的是多线程之间资源同步问题
发表于 2019-07-25 20:51:57 回复(0)

volatile和synchronized的区别

使用上的区别
volatile只能修饰变量,synchronized只能修饰方法和语句块;

对原子性的保证
synchronized可以保证原子性,volatile不能保证原子性;

对可见性的保证
都可以保证可见性,但实现原理不同,volatile对变量加了lock,synchronized使用monitorEnter和monitorExit;

对有序性的保证
都可以保证有序性,但是synchronized并发退化到串行;

其他
synchronized引起阻塞;volatile不会引起阻塞;

发表于 2022-04-15 11:04:47 回复(0)

老生常谈:三短一长选最长

发表于 2019-07-06 12:07:35 回复(2)

volatile就两特性 可见性 禁止指令重排序 用在变量

synchronized 可见性 原子性 禁止指令重排序 都可以用 这样理解对吗

发表于 2019-10-10 00:09:52 回复(0)
牛牛们,记不全的话,就记住一点关键,volatite不支持原子性,synchronized支持原子性
发表于 2023-04-22 23:26:58 回复(0)
这种东西一般人都理解不上去,解释那一大堆也都是百度copy过来的,不如实惠一点,背下来得了,还能锻炼记忆力
发表于 2022-06-18 08:25:02 回复(0)

synchronized关键字和volatile关键字比较:

  • volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。

  • 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞

  • volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。

  • volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

发表于 2021-12-28 11:18:00 回复(0)
volatile只能修饰变量,synchronized可以修饰变量、方法、代码块
发表于 2021-03-22 17:09:35 回复(0)
关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且只能修改变量,而synchronized可以修饰方法,以及代码块。
发表于 2021-03-10 20:32:16 回复(0)
解析:volatile和synchronized的区别
1.作用范围:volatile只能由于变量,synchronized可以用于变量、方法、代码块、类。
2.拥塞:volatile不会导致拥塞,synchronized会导致线程拥塞。
3.作用:volatile和synchronized都能保证数据的可见性和原子性。但关键字volatile解决的下变量在多线程之间的可见性;而synchronized解决的是多线程之间资源同步问题。
发表于 2020-03-21 01:43:36 回复(1)
A: volatile只能修饰变量,synchronize用于修改方法以及代码块

B: volatile不会会发生阻塞,synchronize会发生阻塞

C、D: volatile只能保证可见性和同步性,synchronized可以保证可见性、原子性以及同步性

发表于 2023-08-25 11:05:34 回复(0)
  • volatile关键字提供了可见性保证,确保了变量的读写的一致性,但不提供互斥访问的机制。
  • synchronized关键字提供了互斥访问的机制,确保了同一时间只有一个线程访问共享资源,同时也提供了可见性保证。
发表于 2023-08-15 22:22:10 回复(0)

synchronized关键字和volatile关键字比较:

  • volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量,而synchronized关键字可以修饰方法以及代码块。

  • synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。

  • 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞

  • volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。

  • volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

发表于 2023-07-26 22:56:02 回复(0)
.
发表于 2023-02-21 10:04:13 回复(0)
"volatile" 关键字可以确保可见性和顺序性,但并不能保证原子性。原子性是指一个操作在执行过程中不会被其他线程干扰,要么全部执行完成,要么完全不执行。 下面是一个示例: java Copy Code public class VolatileExample { private volatile int counter = 0; public void increment() { counter++; } } 在上述示例中,我们有一个包含一个 volatile 变量的类,以及一个用于增加该变量值的方法。尽管 counter 字段被声明为 volatile,但它并不能保证增加操作的原子性。 假设有两个线程同时调用 increment() 方法: 线程A: counter++ // 将 counter 加1 线程B: counter++ // 将 counter 加1 由于 ++ 操作不是一个原子操作,虽然 counter 是 volatile 的,但在多线程环境中,线程 A 和线程 B 可能同时读取 counter 的当前值(比如都读取到了 5),然后递增并写回新值。这意味着每个线程只执行了一次递增操作,而没有考虑其他线程的操作。 结果可能如下所示: 线程A: 读取 counter 值 5 线程B: 读取 counter 值 5 线程A: 将 counter 值加1,结果为 6 线程B: 将 counter 值加1,结果也为 6 最终,counter 的值应该是 7,但由于线程 A 和线程 B 同时递增了相同的初始值,结果造成了计数器只加1的情况。 因此,虽然 volatile 变量可以确保可见性,但无法保证复合操作的原子性。如果需要保证原子性,可以使用 synchronized 关键字或者并发包中的原子类(Atomic Classes)等机制。
发表于 2023-10-07 09:05:36 回复(0)

JMM:Java Memory Model,Java内存模型,屏蔽各种硬件和操作系统的内存访问差异

JMM的三大特性:原子性、有序性、可见性

  • 原子性指的是一个或多个操作在CPU执行的过程中不被中断
    • 线程切换带来的原子性问题
  • 有序性指的是程序按照代码的先后顺序执行
    • 编译优化带来的有序性问题
  • 可见性指的是当一个线程修改了共享变量后,其它线程能够立即得知这个修改
    • 缓存导致的可见性问题

synchronized vs volatile

  • synchronized:具有原子性、有序性和可见性,修饰代码块和方法
    • 早期:重量级锁
    • 现在:偏向锁-(升级)>轻量级锁-(膨胀)>重量级锁
  • volatile:具有有序性(使用内存屏障阻止指令重排)和可见性,修饰成员变量
    • 轻量级锁
发表于 2021-12-27 16:40:08 回复(0)