как заставить notify () нормально работать с wait () - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь создать программу, имитирующую очень простую посудомоечную машину, которая имеет три потока. Первая нить отвечает за добавление воды, вторая нить - за открытие дверцы устройства, которая должна заставить нить добавления воды ждать, пока третья нить не уведомит (). система работает, но никогда не останавливается и notify () никогда не работает.

import java.util.logging.Level;
import java.util.logging.Logger;

public class threadexample {
    public static boolean flag = false;

    void Open() throws InterruptedException {
        synchronized (threadexample.this) {
            flag = true;
            Thread.sleep(2000);
            System.out.println("producer thread paused");
            wait();
            System.out.println("Resumed");
        }
    }

    void Close() throws InterruptedException {
        synchronized (threadexample.this) {
            flag = false;
            Thread.sleep(6000);
            System.out.println("System resuming..");
            notifyAll();
            Thread.sleep(2000);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        threadexample closing = new threadexample();
        threadexample openning = new threadexample();

        final Door door = new Door();

        // Create a thread object that calls pc.produce()
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                if (flag == false) {
                    for (int check = 0; check <= 8; check++) {
                        if (check == 1) {
                            System.out.println("Adding Water..." + Thread.currentThread().getName());
                        } else {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
                                if (flag == true) {
                                    try {
                                        closing.Close();
                                    } catch (InterruptedException ex1) {
                                        Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex1);
                                    }
                                }
                            }
                        }
                    }
                }

                try {
                    Thread.sleep(4000);

                } catch (InterruptedException ex) {
                    Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    openning.Open();
                } catch (InterruptedException ex) {
                    Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    closing.Close();
                } catch (InterruptedException ex) {
                    Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }
}

Ответы [ 2 ]

2 голосов
/ 26 февраля 2020

1) Вы звоните wait, не проверяя, произошло ли то, что вы ожидаете, уже произошло. Если вы wait что-то уже произошло, вы будете ждать вечно, потому что notify больше не будет вызываться.

2) Вы звоните sleep, удерживая блокировку. Это не имеет смысла.

3) У вас есть:

            threadexample closing = new threadexample();
            threadexample openning = new threadexample();

и:

        synchronized(threadexample.this) 

Таким образом, вы создаете два экземпляра threadexample и каждый поток синхронизируется на своем собственном экземпляре threadexample. Это тоже неправильно.

0 голосов
/ 26 февраля 2020

Вы никогда не звоните openning.Close(), следовательно, openning.notify() никогда не вызывается. Поэтому Thread t1 ждет вечно. Имейте в виду, что wait() и notify() вызывают монитор объекта и не находятся в состоянии c. Вы хотите использовать threadexample lock = new threadExample().

...