gpt4 book ai didi

java - Volatile 和 ArrayBlockingQueue 以及其他可能的并发对象

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:39:58 24 4
gpt4 key购买 nike

我理解(或者至少我认为我理解;))volatile 关键字背后的原理。查看 ConcurrentHashMap 源代码时,您可以看到所有节点和值都声明为 volatile,这是有道理的,因为可以从多个线程写入/读取值:

static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
...
}

但是,查看 ArrayBlockingQueue 源代码,它是一个正在从多个线程更新/读取的普通数组:

private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)
putIndex = 0;
count++;
notEmpty.signal();
}

如果数组中的元素不是易变的(我知道声明数组本身没有对元素本身有任何影响)?另一个线程不能保存数组的缓存副本吗?

谢谢

最佳答案

请注意 enqueueprivate。查找对它的所有调用(offer(E)、offer(E, long, TimeUnit)、put(E))。请注意,每一个看起来像:

public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
// Do stuff.
enqueue(e);
} finally {
lock.unlock();
}
}

因此您可以得出结论,enqueue 的每次调用都受到 lock.lock() ... lock.unlock() 的保护所以你不需要 volatile 因为 lock.lock/unlock 也是一个内存屏障。

关于java - Volatile 和 ArrayBlockingQueue 以及其他可能的并发对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43069910/

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