原始类型的易失性或同步?

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

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

喜欢,

volatile double x = y; 

synchronized不适用于原始参数。 在这种情况下如何使用synchronized? 当然我不想锁定我的课程,所以不应该使用它。

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

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

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

您无法避免使用volatilesynchronized之一来正确访问multithreading程序中的非final字段。 也就是说,您可能需要synchronized over volatile主要原因是需要使用primefaces比较和设置操作(即它不会是任何性能考虑因素 )。 例如,在multithreading程序中:

 volatile int i = 0; public void foo() { if (i == 0) i = i + 1; } 

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

 int i = 0; public synchronized void foo() { if (i == 0) i = i + 1; } 

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

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

如果你只做一个任务,那么volatile肯定是要走的路。 我相信你知道,但是因为它被提出来了:如果你想做更复杂的操作(例如增加值),你需要同步。 对于任何类型的变量,i ++绝不是线程安全的。 你需要同步。 i ++之类的,因为那实际上是1次以上的操作。

不是:有人表示你可以使用AtomicDouble,但目前在java.util.concurrent.atomic中没有AtomicDouble

如果你在x上做了多个操作,需要在最后将它设置为一个新的值,那么就可以以线程安全的方式做到这一点,没有任何锁定,并且使用比较和线程安全。组。 例:

 AtomicLong x = new AtomicLong(SomeValue); public void doStuff() { double oldX; double newX; do { oldX = x.get(); newX = calculateNewX(oldX); } while (!x.compareAndSet (Double.doubleToLongBits(oldX), Double.doubleToLongBits(newX))); 

这是有效的,因为compareAndSet将查看自上次读取后x的值是否已更改。 如果x已经改变,那么你不得不重新进行计算并重新设置它。

您当然可以实现自己的AtomicDouble,而不是执行这些doubleToLongBits转换。 看看AtomicFieldUpdater。

KDSRathore,你可以使用一些显式锁,或者做一些虚拟的Object object = new Object(),你可以在这个双重的setter / getter中同步

根据oracle文档 ,您可以使用volatile来引用Double对象:

 volatile Double x = y; 

“写入和读取引用始终是primefaces的,无论它们是实现为32位还是64位值。”