原始类型的易失性还是​​同步?

DKS*_*ore 15 java multithreading atomic volatile synchronized

在Java中,如果变量的大小小于或等于32位,则赋值是原子的,但如果大于32位则不是.

在双重或长期分配的情况下,使用什么(易失性/同步)会更有效?

喜欢,

  volatile double x = y;
Run Code Online (Sandbox Code Playgroud)

synchronized不适用于原始参数.在这种情况下如何使用synchronized?当然我不想锁定我的班级,所以this不应该使用.

oxb*_*kes 26

你想做什么?的synchronizedvolatile关键字是Java机制,其可用于确保一致的值由不同的线程读取相同数据中观察到.特别是它们允许您在程序中解释发生之前的关系.

您无法避免使用其中一个volatilesynchronized为了正确访问final多线程程序中的非字段.也就是说,您可能要求synchronized结束的主要原因是需要volatile使用原子比较和设置操作(即,它不会是任何性能考虑因素).例如,在多线程程序中:

volatile int i = 0;

public void foo() { 
    if (i == 0) i = i + 1;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码本质上是不安全的,即使变量的声明为volatile也意味着读取和写入被刷新到主内存 - 这种方法的唯一安全实现将是这样的:

int i = 0;

public synchronized void foo() {
    if (i == 0) i = i + 1;
}
Run Code Online (Sandbox Code Playgroud)

那你应该选哪个?好吧,如果您有多个线程修改依赖于该字段值的字段(即比较和设置),那么这synchronized是唯一安全的解决方案.

值得一提synchronized:性能开销不是问题(在绝大多数情况下).同步性能问题通常是由于不必要的代码瓶颈,死锁或活锁造成的,并且可以在必要时进行缓解.任何纯时钟周期开销都会与应用程序所做的其他事情相形见绌:文件IO,数据库查询,远程处理等.

  • 如果`i`是'double`或`long`,即使只是`i ++`,Volatile也不安全. (4认同)

Yis*_*hai 5

如果你发现对象本身的锁定太重,那么同步就是要走的路.在Java 1.5之前,volatile可能是一个不错的选择,但是现在volatile可以通过在赋值发生的方法上强制执行指令来产生非常大的影响.private final Object X_LOCK = new Object();在设置或获取该double的值时,创建一个单独的对象()并对其进行同步.这将为您提供对锁定的精细控制,这似乎是您所需要的.

在新的并发包中有更多选项,例如AtomicReference,如果你真的需要避免同步,它可能是volatile的一个很好的替代品.