将volatile和synchronized混合为读写锁

Hon*_*gbo 7 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--;
}
Run Code Online (Sandbox Code Playgroud)

Yon*_*oni 5

是的,这是常见的,至少在一定程度上:)

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

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


Ste*_*n C 3

考虑一个原始类型变量,有大量线程读取和少量线程写入,以下代码可以正常工作吗?

我想是这样。

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

我认为是的,前提是读取操作的数量超过写入请求。然而:

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

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

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