使用同步会影响性能。 volatile 能否与 synchronized 结合使用以降低性能开销?例如,Counter 的实例将在多个线程之间共享,每个线程都可以访问 Counter 的公共(public)方法。在下面的代码中,volatile 用于 getter,synchronized 用于 setter
public class Counter
{
private volatile int count;
public Counter()
{
count = 0;
}
public int getCount()
{
return count;
}
public synchronized void increment()
{
++count;
}
}
请告诉我这可能会在哪种情况下中断?
最佳答案
是的,你绝对可以。事实上,如果您查看AtomicInteger
的源代码,它们本质上就是这样做的。 AtomicInteger.get
仅返回 value
,这是一个 volatile int
( link )。与您所做的和他们所做的唯一真正的区别是他们使用 CAS 进行增量而不是同步。在现代硬件上,CAS 可以消除任何互斥;在较旧的硬件上,JVM 将在增量周围放置某种互斥体。
volatile 读取与非 volatile 读取速度差不多,因此读取速度会非常快。
不仅如此,volatile
字段也保证不会撕裂:参见 JLS 17.7 ,它指定 volatile
long
和 double
不受单词撕裂的影响。因此,您的代码既可以使用 long
也可以使用 int
。
正如 Diego Frehner 指出的那样,如果您在增量发生时“恰好”获得值,您可能看不到增量的结果——您将看到之前或之后的结果。当然,如果 get
是同步的,您将拥有与读取线程完全相同的行为——您将看到增量前或增量后的值。所以这两种方式实际上是一样的。换句话说,说你不会看到正在发生的值(value)是没有意义的——除非你的意思是撕裂,(a) 你不会得到,(b) 你永远不会想要。
关于java - volatile 同步组合以提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11681326/