gpt4 book ai didi

java - 为什么下面的生产者消费者代码不需要volatile变量?

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:03:00 27 4
gpt4 key购买 nike

在我看来,生产者线程和消费者线程都可以分别缓存计数并因此做出错误的决定。如果变量不是易变的,count++ 可能只是更新缓存吧?

class Buffer {
private char [] buffer;
private int count = 0, in = 0, out = 0;

Buffer(int size)
{
buffer = new char[size];
}

public synchronized void Put(char c) {
while(count == buffer.length)
{
try { wait(); }
catch (InterruptedException e) { }
finally { }
}
System.out.println("Producing " + c + " ...");
buffer[in] = c;
in = (in + 1) % buffer.length;
count++;
notify();
}

public synchronized char Get() {
while (count == 0)
{
try { wait(); }
catch (InterruptedException e) { }
finally { }
}
char c = buffer[out];
out = (out + 1) % buffer.length;
count--;
System.out.println("Consuming " + c + " ...");
notify();
return c;
}
}

最佳答案

不,这两个方法都是用synchronized关键字定义的,这意味着它们永远不会同时执行,而且内存将被同步。在 synchronized block 中访问的变量永远不需要 volatile

如果我们使用 Java 提供的其他同步机制,例如 ReentrantReadWriteLock 而不是 synchronized 我们也不需要 volatile,因为正确使用的锁具有相同的内存保证(使用官方语言发生前关系)。

Memory Consistency Properties

Actions prior to "releasing" synchronizer methods such as Lock.unlock, Semaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.

关于java - 为什么下面的生产者消费者代码不需要volatile变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45728684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com