gpt4 book ai didi

java - 在 Java 中使用 wait() 和 notify() 被阻止

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

我正在使用 Java 中的 wait()notify() 编写生产者和消费者代码。Thread-0 创建并在 produce() 上调用,Thread-1 创建并在 consume() 上调用。

public class Processor {

private volatile List<Integer> list = new ArrayList<>();
private final int MAX_CAPACITY = 5;
Object lock = new Object();

public void produce() throws InterruptedException {

while (true) {

while (list.size() == MAX_CAPACITY) {
System.out.println("List is full! Producer is Waiting....");
synchronized (lock) {
lock.wait();
}
}

synchronized (lock) {
int random = new Random().nextInt(100);
list.add(random);
System.out.println("Added to list:" + random);
lock.notify();
}
}
}

public void consume() throws InterruptedException {

while (true) {

while (list.size() == 0) {
System.out.println("List is empty!! Consumer is Waiting...");
synchronized (lock) {
lock.wait();
}
}

synchronized (lock) {
int i = list.remove(0);
System.out.println("Removed from list:" + i);
lock.notify();
}
}
}
}

问题是在执行过程中,程序在 produce() 之后停止:

List is empty!! Consumer is Waiting...
Added to list:22
Added to list:45
Added to list:72
Added to list:91
Added to list:51
List is full! Producer is Waiting....

我不明白这里有什么问题。我不知何故发现将 while 循环中的代码包装在 produce()consume() 中的 synchronized block 中解决问题。

生产()

synchronized (lock) {
while (list.size() == MAX_CAPACITY) {
System.out.println("List is full! Producer is Waiting....");

lock.wait();
}

消费

synchronized (lock) {
while (list.size() == 0) {
System.out.println("List is empty!! Consumer is Waiting...");

lock.wait();
}
}

这里有什么问题?是线程饥饿还是死锁?

编辑:调用类:

public class App {
public static void main(String[] args) {
final Processor processor = new Processor();

Runnable r1 = new Runnable() {

@Override
public void run() {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
};

Runnable r2 = new Runnable() {

@Override
public void run() {
try {
processor.consume();
} catch (InterruptedException e) {

e.printStackTrace();
}
}
};

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

t1.start();
t2.start();


}
}

最佳答案

当您执行 list.size() 时,它不是线程安全的,并且无法保证您会在另一个线程中看到该值发生更改。如果 JIT 检测到您没有在该线程中更改它,它甚至可以内联该值。

通过将 synchronized block 放在循环之外,您可以确保值的更改是可见的(因为它也在 while(true) 循环内)。

关于java - 在 Java 中使用 wait() 和 notify() 被阻止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38498930/

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