How can the wait() and notify() methods be called on Objects that are not threads?

前端 未结 9 905
耶瑟儿~
耶瑟儿~ 2020-11-29 19:00

How can the wait() and notify() methods be called on Objects that are not Threads? That doesn\'t really make sense, does it?

Surely, it mus

相关标签:
9条回答
  • 2020-11-29 19:22
    1. Wait and notify is not just normal methods or synchronization utility, more than that they are communication mechanism between two threads in Java. And Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized. Remember synchronized and wait notify are two different area and don’t confuse that they are same or related. Synchronized is to provide mutual exclusion and ensuring thread safety of Java class like race condition while wait and notify are communication mechanism between two thread.
    2. Locks are made available on per Object basis, which is another reason wait and notify is declared in Object class rather then Thread class.
    3. In Java in order to enter critical section of code, Threads needs lock and they wait for lock, they don't know which threads holds lock instead they just know the lock is hold by some thread and they should wait for lock instead of knowing which thread is inside the synchronized block and asking them to release lock. this analogy fits with wait and notify being on object class rather than thread in Java.

    Analogy : a Java thread is a user and the toilet is a block of code which the thread wishes to execute. Java provides a way to lock the code for a thread which is currently executing it using the synchorinized keywokd, and making other threads that wish to use it wait until the first thread is finished. These other threads are placed in the waiting state. Java is NOT AS FAIR as the service station because there is no queue for waiting threads. Any one of the waiting threads may get the monitor next, regardless of the order they asked for it. The only guarantee is that all threads will get to use the monitored code sooner or later.

    Source

    If you look at the following producer and consumer code:
    sharedQueue Object acts inter-thread communication between producer and consumer threads.

    import java.util.Vector;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class ProducerConsumerSolution {
    
        public static void main(String args[]) {
            Vector<Integer> sharedQueue = new Vector<Integer>();
            int size = 4;
            Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer");
            Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer");
            prodThread.start();
            consThread.start();
        }
    }
    
    class Producer implements Runnable {
    
        private final Vector<Integer> sharedQueue;
        private final int SIZE;
    
        public Producer(Vector<Integer> sharedQueue, int size) {
            this.sharedQueue = sharedQueue;
            this.SIZE = size;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 7; i++) {
                System.out.println("Produced: " + i);
                try {
                    produce(i);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
                }
    
            }
        }
    
        private void produce(int i) throws InterruptedException {
    
            // wait if queue is full
            while (sharedQueue.size() == SIZE) {
                synchronized (sharedQueue) {
                    System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: "
                            + sharedQueue.size());
    
                    sharedQueue.wait();
                }
            }
    
            // producing element and notify consumers
            synchronized (sharedQueue) {
                sharedQueue.add(i);
                sharedQueue.notifyAll();
            }
        }
    }
    
    class Consumer implements Runnable {
    
        private final Vector<Integer> sharedQueue;
        private final int SIZE;
    
        public Consumer(Vector<Integer> sharedQueue, int size) {
            this.sharedQueue = sharedQueue;
            this.SIZE = size;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    System.out.println("Consumed: " + consume());
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
                }
    
            }
        }
    
        private int consume() throws InterruptedException {
            //wait if queue is empty
            while (sharedQueue.isEmpty()) {
                synchronized (sharedQueue) {
                    System.out.println("Queue is empty " + Thread.currentThread().getName()
                                        + " is waiting , size: " + sharedQueue.size());
    
                    sharedQueue.wait();
                }
            }
    
            //Otherwise consume element and notify waiting producer
            synchronized (sharedQueue) {
                sharedQueue.notifyAll();
                return (Integer) sharedQueue.remove(0);
            }
        }
    }
    

    Source

    0 讨论(0)
  • 2020-11-29 19:25

    In Java all Object implements these two methods, obviously if there are not a monitor those two methods are useless.

    0 讨论(0)
  • 2020-11-29 19:28

    Think using a real life example, a washroom. When you want to use the washroom at your office, you have two options to make sure no one else will come to the washroom once you are using it.

    1. Lock the washroom door, so everyone else will know that it's used by someone else when they try to open the door
    2. Go to each person in the office, lock them to their chairs (or table, or whatever), go to washroom.

    Which option would you take?

    Yes, it's the same in the Javaland!.

    So in the above story,

    • Washroom = Object you want to lock (that only you need to use)
    • Your staff colleagues = other threads that you want to keep out

    So just like in real life, when you have some private business, you lock that object. And when you are done with that object, you let go of the lock!.

    (Yes yes!, this is a very simple description on what happens. Of course the real concept is slightly different from this, but this is a starting point)

    0 讨论(0)
提交回复
热议问题