繁体   English   中英

易失性同步组合以提高性能

[英]volatile synchronized combination for performance

使用同步时会对性能产生影响。 volatile可以与synchronized结合使用以降低性能开销吗? 例如,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只返回value ,这是一个volatile int链接 )。 与你所做的和他们做的唯一真正的区别是他们使用CAS来增加而不是同步。 在现代硬件上,CAS可以消除任何互斥; 在较旧的硬件上,JVM会在增量周围放置某种互斥。

易失性读取速度与非易失性读取速度一样快,因此读取速度非常快。

不仅如此,保证不会撕裂volatile区域:参见JLS 17.7 ,它规定了volatile long s和double s不会受到撕裂。 所以你的代码可以使用longint一样long

正如迭戈弗雷纳所指出的那样,如果你得到增量发生的“正确”值,你可能看不到增量的结果 - 你会看到之前或之后。 当然,如果get是同步的,那么你从read线程中获得完全相同的行为 - 你要么看到前递增值或后递增值。 所以这两种方式都是一样的。 换句话说,说你不会看到正在发生的价值是没有意义的 - 除非你的意思是撕裂,(a)你不会得到和(b)你永远不会想要的。

1.我曾亲自使用的这种机制volatile 联合 synchronized

2.可以单独使用 synchronized ,并且您将始终获得一致的结果,但仅使用 volatile 不会始终产生相同的结果。

3.这是因为挥发性关键字不是原始的同步。 它只是防止在线程上缓存值 ,但它不会阻止两个线程修改相同的值并同时将其写回。

4. volatile给予没有锁的线程的并发访问 ,但是然后使用synchronized允许一个线程访问该类以及类中的所有同步方法。

5. 使用 volatile and synchronized都会这样做....

volatile -将更改的值反映到线程,并防止缓存,

synchronized -但是使用synchronized关键字,将确保只有一个线程可以访问类的同步方法。

调用getCount()时,您不会总是获得最实际的计数。 AtomicInteger可能适合您。

使用两者都不会带来性能提升。 Volatile保证在通过防止缓存并行执行的线程读取/写入变量时变量的值是一致的。 同步 ,当应用于方法时(如您的示例中所做),仅允许单个线程一次输入该方法并阻止其他方法,直到执行完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM