Я обновляю свои знания на Java и пытаюсь написать многопоточную программу Wait and Notify (Producer, Consumer). Идея состоит в том, что у двух есть поток производителей, который добавляет данные в список массивов и уведомляет потребительский поток, который ожидает блокировки, достигнутой потоком производителя. Код дает вывод не ожидаемый результат.Java multi threading wait and notify
Но что я ожидал увидеть это
Если вы видите оба потребительские потоки ставятся на ожидание. Когда 1-й поток производителя добавляет данные в arraylist и отправляет сигнал notifyall всем ожидающим потокам. Я припарковал поток Producer на 10 секунд, так что ожидающий поток успеет выбрать список массивов и отобразить содержимое массива. На данный момент размер массива должен быть 1.
package Threads_New;
import java.util.ArrayList;
import java.util.List;
public class Producer_Consumer2 {
List<String> sharedList = new ArrayList();
int count = 0;
Object o = new Object();
public void producer()
{
synchronized (o) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "-Adding a value-" + count);
count++;
sharedList.add("Apple-" + count);
o.notifyAll();
System.out.println("The Waiting thread is notified");
try {
Thread.sleep(10000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public void consumer() {
System.out.println(Thread.currentThread().getName()
+ "- came inside consumer");
synchronized (o) {
try {
o.wait();
System.out.println(Thread.currentThread().getName()
+ "- Notification recieved");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("I was waiting and now got notified");
for (String s : sharedList) {
System.out.println("Data from the sharedList is:" + s);
}
}
}
public void ThreadStarter() {
Thread[] T = new Thread[3];
int run = 0;
while (run < 2) {
T[run] = new Thread(new Runnable() {
@Override
public void run() {
producer();
}
});
T[run + 1] = new Thread(new Runnable() {
@Override
public void run() {
consumer();
}
});
/*
* for(int i=0;i<10;i++) { t1.start(); t2.start(); }
*/
T[run].start();
T[run + 1].start();
run++;
}
/*
* for(int i=0;i<21;i++) { try{ T[i].join(); T[i+1].join();
* }catch(InterruptedException ex) { ex.printStackTrace(); } }
*/
}
public static void main(String[] args) {
Producer_Consumer2 pc = new Producer_Consumer2();
pc.ThreadStarter();
}
}
Если это на самом деле предполагается использовать рассмотреть возможность использования BlockingQueue вместо https://docs.oracle.com/javase/8/docs/api/java/ util/concurrent/BlockingQueue.html – kervin
Попытка управлять многопоточным кодом с помощью спальных мест никогда не заканчивается. – sstan
Почему существует ожидание у вашего потребителя? Вы уверены, что понимаете, как эти примитивы работают вместе с синхронизированными? Как правило, гораздо проще использовать утилит библиотеки более высокого уровня в параллельном пакете. – pvg