Задать вопрос
@daniil14056

Синхронизация потоков java? System.out.print() изменил результат программы, как?

Изучаю java. Кто может объяснить, чем вызов wait() у потока управления в которой передал другой поток вызовом wait(), отличается от вызова notify() у того же потока.Полная статья . Не могу понять вывод проги. Почему вывод не 1 0 1 0 1 0.
И еще более сложный вопрос. Почему, когда я вставляю System.out.println("Put run " +i); в конец цикла метода put() в классе Producer.(Закоментированно в конце) вывод изменяется.

public class ThreadsApp {
  
    public static void main(String[] args) {
          
        Store store=new Store();
        Producer producer = new Producer(store);
        Consumer consumer = new Consumer(store);
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}
// Класс Магазин, хранящий произведенные товары
class Store{
   private int product=0;
   public synchronized void get() {
      while (product<1) {
         try {
            wait();
         }
         catch (InterruptedException e) {
         }
      }
      product--;
      System.out.println("Покупатель купил 1 товар");
      System.out.println("Товаров на складе: " + product);
      notify();
   }
   public synchronized void put() {
       while (product>=3) {
         try {
            wait();
         }
         catch (InterruptedException e) { 
         } 
      }
      product++;
      System.out.println("Производитель добавил 1 товар");
      System.out.println("Товаров на складе: " + product);
      notify();
   }
}
// класс Производитель
class Producer implements Runnable{
  
    Store store;
    Producer(Store store){
       this.store=store; 
    }
    public void run(){
        for (int i = 1; i < 6; i++) {
            store.put();   
            ///  System.out.println("Put run  " +i);  /// Этот вызов принта меняет вывод программы на 1 0 1 0 1.. ПОЧЕМУ,??????
   }
    }
}
// Класс Потребитель
class Consumer implements Runnable{
     Store store;
    Consumer(Store store){
       this.store=store; 
    }
    public void run(){
        for (int i = 1; i < 6; i++) {
            store.get();
        }
    }
}

ВЫВОД ПРОГРАММЫ
Производитель добавил 1 товар
Товаров на складе: 1
Производитель добавил 1 товар
Товаров на складе: 2 //0 если вставить System.out.print();
Производитель добавил 1 товар
Товаров на складе: 3 // 1
Покупатель купил 1 товар
Товаров на складе: 2 // 0
Покупатель купил 1 товар
Товаров на складе: 1
Покупатель купил 1 товар
Товаров на складе: 0
Производитель добавил 1 товар
Товаров на складе: 1
Производитель добавил 1 товар
Товаров на складе: 2
Покупатель купил 1 товар
Товаров на складе: 1
Покупатель купил 1 товар
Товаров на складе: 0
  • Вопрос задан
  • 248 просмотров
Подписаться 3 Сложный Комментировать
Пригласить эксперта
Ответы на вопрос 1
zagayevskiy
@zagayevskiy Куратор тега Java
Android developer at Yandex
Это типичная ситуация гонки потоков. notify() будит поток, но не гарантирует, что он начнёт выполнять работу прямо сейчас. Producer успевает раньше, что неудивительно. При вставке длительной операции (вывод в консоль) - перестаёт успевать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы