简体   繁体   中英

how to make notify() works properly with wait()

I am trying to make a program simulating a very simple dishwasher which has three threads. The first thread is responsible for adding water, the second thread for opening the door of the device which should force the adding water thread to wait until the third thread notify(). the system runs but it never stops and the notify() never works.

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();
    }
}

1) You call wait without checking whether or not the thing you are waiting for has already happened. If you wait for something that has already happened, you will wait forever because notify will not be called again.

2) You call sleep while holding the lock. That doesn't make sense.

3) You have:

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

and:

        synchronized(threadexample.this) 

So you create two instances of threadexample and each thread synchronizes on its own instance of threadexample . That's not right either.

You never actually call openning.Close() , hence openning.notify() is never called. Therefore, Thread t1 waits forever. Mind you, wait() and notify() call the Object's monitor and are not static. You want to use threadexample lock = new threadExample() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM