使用同步时会产生性能影响.可以与易失性组合使用同步来降低性能开销吗?例如,Counter的实例将在许多线程之间共享,每个线程都可以访问Counter的公共方法.在下面的代码中,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只是返回值,这是一个volatile int(
link).与您所做的工作和他们所做的工作唯一的真正区别在于它们使用CAS进行增量而不是同步.在现代硬件上,CAS可以消除任何相互排斥;在较旧的硬件上,JVM会在增量之间放置一些互斥体.
挥发性阅读量与非易失性读数大约相同,读取速度将非常快.
不仅如此,挥之不去的领域也不会被撕裂:参见JLS 17.7,其中规定了挥发性的长时间和双打不会被撕裂.所以你的代码可以使用一个很长的以及一个int.
如Diego Frehner所指出的那样,如果您获得“正确为”增量的值,您可能看不到增量的结果 – 您将看到之前或之后.当然,如果get被同步,你将会从读取的线程中完全相同的行为 – 你可以看到before-increment或post-increment的值.所以这样也是一样的.换句话说,说你不会看到价值观,这是没有意义的 – 除非你的意思是撕裂,否则你不会得到,(b)你永远不会想要的.