多线程Java等待在while循环内/外同步
我正在研究消费者/生产者的问题,以了解Java中的并发性问题。我的问题可能与C/P问题本身相邻。在下面的代码片段中,如果我使用版本1,程序似乎运行良好,而使用版本2,我似乎在一段时间后出现死锁
我只发布生产者类,因为不需要消费者类
- 缓冲区是生产者存放产出的地方
- 我只是把1的整数加进去
- 而(正确)是保持线程持续运行
我的问题是:我知道在Java API中调用wait()的结构是:synchronized->;而->;等待但在这种情况下会发生什么:while->;同步->;等待如果在wait()期间,使用者调用notifyAll(),生产者再次醒来,那么代码不会从调用wait()的地方继续,最终会到达while(buffer.remainingCapacity()==0)
我已经四处挖掘,看看是否有人问过这个问题,但找不到任何具体的问题
第1版
public class Producer extends Thread {
ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<>(10);
public Producer(ArrayBlockingQueue<Integer> buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
synchronized(buffer) {
while (buffer.remainingCapacity() == 0) {
try {
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
try {
synchronized (buffer) {
buffer.add(1);
System.out.println("Producer active with remaining capacity: " + buffer.remainingCapacity());
buffer.notifyAll();
}
} catch (IllegalStateException ex) {
ex.printStackTrace();
}
}
}
}
第2版
public class Producer extends Thread {
ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<>(10);
public Producer(ArrayBlockingQueue<Integer> buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
while (buffer.remainingCapacity() == 0) {
synchronized (buffer) {
try {
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
try {
synchronized (buffer) {
buffer.add(1);
System.out.println("Producer active with remaining capacity: " + buffer.remainingCapacity());
buffer.notifyAll();
}
} catch (IllegalStateException ex) {
ex.printStackTrace();
}
}
}
}
就为了它,这是另一个版本代码的问题,似乎是工作。我只是把它放在这里,以防它对其他人有帮助,或者如果有人能告诉我它是否错,为什么错。与上面的版本相比,这个版本的wait和notifyAll方法在代码中的位置发生了“翻转”
while(true) {
while(buffer.remainingCapacity() == 0){
synchronized (buffer){
buffer.notifyAll();
}
}
try {
buffer.add(1);
System.out.println("Producer active with remaining capacity: " + buffer.remainingCapacity());
} catch (IllegalStateException ex) {
synchronized (buffer){
try {
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
共 (0) 个答案