Один из потоков простаивает
У меня есть такой класс Store, который представляет из себя "хранилище элементов" и 2 потока. Один бесконечно добавляет элемент(ProducerThread) в очередь, а второй бесконечно забирает(ConsumerThread) из очереди. Тот, который добавляет, отрабатывает нормально, а тот, который забирает - простаивает. Я запустил debug и посмотрел работу ConsumerThread , но только через debug он работает как надо. Почему в debug он работает нормально и где я ошибся ?
public class Store {
private static final Random random = new Random();
private static Deque<Integer> listOfNumbers = new LinkedList<>();
private final static int STORAGE_CAPACITY = 10;
public synchronized void produce() {
while (listOfNumbers.size() == STORAGE_CAPACITY) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int element = random.nextInt(50);
listOfNumbers.add(element);
System.out.println("Added element: " + element + "\nStorage size: " + getStorageSize() + "\n" + getListOfNumbers());
notify();
}
public synchronized void consume() {
while (listOfNumbers.size() == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int element = listOfNumbers.removeFirst();
System.out.println("Received element: " + element + "\nStorage size: " + getStorageSize() + "\n" + getListOfNumbers());
notify();
}
public int getStorageSize() {
return listOfNumbers.size();
}
public Deque<Integer> getListOfNumbers() {
return listOfNumbers;
}
}
public class ProducerThread implements Runnable {
Store store = new Store();
@Override
public void run() {
while (true) {
store.produce();
}
}
}
public class ConsumeThread implements Runnable {
private Store store = new Store();
@Override
public void run() {
while (true) {
store.consume();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class NumberStorageDemo {
public static void main(String[] args) {
Thread producer = new Thread(new ProducerThread(), "Producer");
Thread consumer = new Thread(new ConsumeThread(), "Consumer");
producer.start();
consumer.start();
}
}
Ответы (1 шт):
Проблема в том, что каждый класс создает свой экземпляр Store, со своим списком для хранения объектов.
Писатель пишет в свой список, но читатель пробует доставать из совершенно другого (всегда пустого списка).
Исправить можно создав только одно хранилище:
public class ProducerThread implements Runnable {
final private Store store;
public ProducerThread(Store store) {
this.store = store;
}
...
}
public class ConsumerThread implements Runnable {
final private Store store;
public ConsumerThread(Store store) {
this.store = store;
}
...
}
Store sharedStore = new Store();
Thread producer = new Thread(new ProducerThread(sharedStore), "Producer");
Thread consumer = new Thread(new ConsumeThread(sharedStore), "Consumer");