混合 volatile 和synchronized作为读写锁

发布于 2024-10-04 20:11:46 字数 624 浏览 6 评论 0原文

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

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

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

目前这对我来说效果很好,但我觉得同时使用 易失性 和同步有点多余。

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--;
}

Consider a primitive type variable with lots of threads reading and a few threads writing, will the following code work correctly?

If it will, does it provide better performance than 1). declaring synchronized on all the methods; 2). using an explicit ReadWriteLock?

Is this a common pattern? If not, what pattern is usually used in this situation?

This currently works fine for me, but I feel it's a bit redundant to use both volatile and 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--;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

临走之时 2024-10-11 20:11:46

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

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

(模式#5,廉价的读写锁技巧)

Yes, it is common, at least to a certain degree :)

The pattern you are using is described in this IBM article -> http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html

(pattern #5, cheap read-write lock trick)

烟─花易冷 2024-10-11 20:11:46

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

我想是的。

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

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

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

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

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

Consider a primitive type variable with lots of threads reading and a few threads writing, will the following code work correctly?

I think so.

If it will, does it provide better performance than 1). declaring synchronized on all the methods; 2). using an explicit ReadWriteLock?

I think so, provided that read operations outnumber write requests. However:

  • Unless this counter is highly contended, it probably doesn't matter. Don't waste your time micro-optimizing something unless you have evidence that it is (or will be) a bottleneck.
  • If it really matters to you, benchmark it.
  • Don't be surprised if the relative performance depends on JVM versions / patch levels, JVM options and hardware; e.g. numbers of processors and memory architecture.

Is this a common pattern? If not, what pattern is usually used in this situation?

I don't know if this is common. But my gut feeling is that the most common approach is to just use regular synchronization, and not worry about it. Unless you are dealing with a highly contended data structure, the performance difference between the various approaches will be insignificant to overall application performance.

半枫 2024-10-11 20:11:46

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

I'm sure it provides better performance, since there is no locking, but whether it is correct depends on the intent of the code. For sure, the behaviour is different from the synchronized case. Whether the behaviour is similar to the lock case depends on where you lock.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文