- Я использовал if вместо while< /code>.
- Я использовал notify вместо notifyAll.
Код: Выделить всё
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java -javaagent:/opt/idea/lib/idea_rt.jar=44073:/opt/idea/bin -Dfile.encoding=UTF-8 -classpath /home/xun/Desktop/myworkspace/java-playground/target/classes SharedResource
Produced 0
ConsumerC Consumed 0
Produced 1
ConsumerC Consumed 1
ConsumerA Consumed 1
Produced 2
ConsumerC Consumed 2
ConsumerA Consumed 2
Produced 3
ConsumerC Consumed 3
ConsumerA Consumed 3
Produced 4
ConsumerA Consumed 4
ConsumerC Consumed 4
ConsumerA Consumed 4
ConsumerC Consumed 4
ConsumerA Consumed 4
ConsumerC Consumed 4
ConsumerA Consumed 4
ConsumerC Consumed 4
ConsumerA Consumed 4
Produced 5
Проанализируйте причину такого поведения. Ниже мой код:
Код: Выделить всё
public class SharedResource {
private int data;
private boolean available = false;
public synchronized void produce(int value) throws InterruptedException {
while (available) {
wait();
}
data = value;
available = true;
System.out.println("Produced " + value);
// notifyAll();
notify();
}
public synchronized int consumeWithIf() throws InterruptedException {
if (!available) {
wait();
}
System.out.println(Thread.currentThread().getName() + " Consumed " + data);
available = false;
// notifyAll();
notify();
return data;
}
public static void main(String[] args) {
SharedResource sharedResource = new SharedResource();
Thread producer = new Thread(new Producer(sharedResource));
Thread consumerA = new Thread(new ConsumerA(sharedResource), "ConsumerA");
Thread consumerC = new Thread(new ConsumerC(sharedResource), "ConsumerC");
producer.start();
consumerA.start();
consumerC.start();
}
}
class Producer implements Runnable {
private SharedResource resource;
public Producer(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
resource.produce(i);
// Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
class ConsumerA implements Runnable {
private SharedResource resource;
public ConsumerA(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
int value = resource.consumeWithIf();
// Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
class ConsumerC implements Runnable {
private SharedResource resource;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
int value = resource.consumeWithIf();
// Thread.sleep(700);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public ConsumerC(SharedResource resource) {
this.resource = resource;
}
}
Я понимаю, что использование notifyAll() вместо notify и while вместо if может предотвратить определенные проблемы с синхронизацией. Однако меня особенно смущает, почему программа зависает после печати Produced 5, несмотря на то, что ожидается, что потребительский поток должен использовать созданное значение и позволить программе продолжить работу.
Подробнее здесь: https://stackoverflow.com/questions/793 ... notify-and