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
你想做什么?的synchronized
和volatile
关键字是Java机制,其可用于确保一致的值由不同的线程读取相同数据中观察到.特别是它们允许您在程序中解释发生之前的关系.
您无法避免使用其中一个volatile
或synchronized
为了正确访问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,数据库查询,远程处理等.
如果你发现对象本身的锁定太重,那么同步就是要走的路.在Java 1.5之前,volatile可能是一个不错的选择,但是现在volatile可以通过在赋值发生的方法上强制执行指令来产生非常大的影响.private final Object X_LOCK = new Object();
在设置或获取该double的值时,创建一个单独的对象()并对其进行同步.这将为您提供对锁定的精细控制,这似乎是您所需要的.
在新的并发包中有更多选项,例如AtomicReference,如果你真的需要避免同步,它可能是volatile的一个很好的替代品.