将volatile和synchronized混合为读写锁

时间:2010-11-27 02:40:33

标签: java concurrency volatile synchronized readwritelock

考虑一个原始类型变量,其中包含许多线程读取和几个线程写入,以下代码是否可以正常工作?

如果愿意,它是否提供比1)更好的性能。声明所有方法的同步; 2)。使用显式的ReadWriteLock?

这是一种常见的模式吗?如果没有,在这种情况下通常使用什么模式?

目前这对我来说很好,但我觉得使用volatile和synchronized会有点多余。

private volatile int value = 1;

public void func1()
{
    if (value == 1) {
        // do something
    }
}

public void func2()
{
    if (value == 2) {
        // do something
    }
}

public void func3()
{
    if (value == 3) {
        // do something
    }
}

public synchronized void increase()
{
    if (value < 10) value++;
}

public synchronized void decrease()
{
    if (value > 0) value--;
}

3 个答案:

答案 0 :(得分:5)

是的,这是常见的,至少在某种程度上是这样的:)

您正在使用的模式在此IBM文章中描述 - &gt; http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html

(模式#5,便宜的读写锁定技巧)

答案 1 :(得分:3)

  

考虑一个原始类型变量,其中包含许多线程读取和几个线程写入,以下代码是否可以正常工作?

我是这么认为的。

  

如果愿意,它是否提供比1)更好的性能。声明所有方法的同步; 2)。使用显式的ReadWriteLock?

我认为是这样,只要读取操作数量超过写入请求。但是:

  • 除非这个反击是高度争议的,否则可能并不重要。除非你有证据证明它是(或将是)瓶颈,否则不要浪费你的时间微观优化。
  • 如果它对你真的很重要,那就进行基准测试吧。
  • 如果相对性能取决于JVM版本/补丁级别,JVM选项和硬件,请不要感到惊讶;例如处理器数量和内存架构。
  

这是一种常见的模式吗?如果没有,在这种情况下通常使用什么模式?

我不知道这是否常见。但我的直觉是,最常见的方法是只使用常规同步,而不用担心它。除非您正在处理高度竞争的数据结构,否则各种方法之间的性能差异对整体应用程序性能来说无关紧要。

答案 2 :(得分:0)

我确信它提供了更好的性能,因为没有锁定,但它是否正确取决于代码的意图。当然,行为与同步的情况不同。行为是否与锁定案例相似取决于您锁定的位置。