【发布时间】:2022-12-10 10:54:06
【问题描述】:
我有两种方法可以从循环缓冲区中添加和删除元素
第一个实现:
synchronized void add(byte b) throws InterruptedException {
if(availableObjects == size) wait();
buffer[(tail+1)%size] = b ;
tail++;
availableObjects++;
notifyAll();
}
synchronized byte remove() throws InterruptedException {
if(head==tail) wait();
Byte element = buffer[head%size];
head ++ ;
availableObjects--;
notifyAll();
return element;
}
和第二个实现:
private final Object addLock= new Object ();
private final Object removeLock=new Object ();
void add (byte b) throws InterruptedException{
synchronized (addLock){
while (availaibleObjects.get () == size) addLock.wait();
buffer [tail]= b;
tail = [tail + 1) % size;
availaibleObjects.incrementAndGet();}
synchronized (removeLock){ // why we added this block ?
removeLock.notifyAll();}
}
byte remove () throws InterruptedException{
byte element;
synchronized (removeLock){
while (availaibleObjects.get () == 0) removeLock.wait() ;
element = buffer[head] ;
head=(head + 1) % size;
availaibleObjects.decrementAndGet();}
synchronized (addLock){ // why we added this block ?
addLock.notifyAll();}
return element;}
我的问题是为什么在方法的第二次实现中我们添加了第二个同步块?
- 从第一个实现中我了解到两个线程不能同时添加和删除。
- 从第二个实现开始,两个线程可以同时添加和删除,但我不明白为什么要添加这些块:
synchronized (removeLock){ // why we added this block ? removeLock.notifyAll();} synchronized (addLock){ // why we added this block ? addLock.notifyAll();} return element;}
【问题讨论】:
-
代码必须位于
synchonized块中才能执行notifyAll()和wait调用。 -
我猜想所有的变异操作(即添加和删除)应该共享同一个锁。我无法想象同时执行添加和删除是安全的。
-
@K.Nicholas 是的,我明白了,但为什么我们将
notifyAll()添加到同步块中?我们可以在第一个街区做到这一点 -
同步块特定于对象。 RTFM。
-
@K.Nicholas 明白了,非常感谢。
标签: java multithreading concurrency locking