代码之家  ›  专栏  ›  技术社区  ›  Waseem

wait()是否等待被引用对象或引用本身(如果对引用调用)?

  •  1
  • Waseem  · 技术社区  · 6 年前

    在这种情况下,是否会通知线程1(在等待引用而不是对象本身时)?

    static Object lock=new Object();
    //Thread 1:
    Object reference=lock;
    reference.wait();
    
    //Thread 2:
    lock.notify();
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Lalit Mehra    6 年前

    等待引用或该引用指向的对象是相同的,因为在对象上获得了锁。无论有多少引用,如果它们指向内存中的同一对象wait()、notify(),notifyall()都将无缝工作。查看下面的代码。

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.concurrent.ArrayBlockingQueue;
    
    public class ProducerConsumer {
    
    private Queue<Integer>      queue   = new ArrayBlockingQueue<>(10);
    private LinkedList<Integer> list    = new LinkedList<>();
    int                         limit   = 10;
    
    public static void main(String[] args) {
    
        final ProducerConsumer pc = new ProducerConsumer();
        final ProducerConsumer pcRef = pc;
    
        Thread producer = new Thread(new Runnable() {
            int i = 1;
    
            @Override
            public void run() {
                while (true) {
                    synchronized (pcRef) {
                        while (pc.limit == pc.list.size()) {
                            try {
                                pcRef.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        pc.list.add(i);
                        System.out.println("Producer @work : " + pc.list.size());
                        pcRef.notify();
                    }
    
                }
            }
        });
    
        Thread consumer = new Thread(new Runnable() {
    
            @Override
            public void run() {
                while (true) {
                    synchronized (pc) {
                        while (0 == pc.list.size()) {
                            try {
                                pc.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        int val = pc.list.removeFirst();
                        System.out.println("Consumer @work : " + pc.list.size() + " : " + val);
                        pc.notify();
                    }
    
                }
            }
        });
    
        producer.start();
        consumer.start();
    
        try {
            producer.join();
            consumer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
    }
    
    }
    

    注释下面的行,您将看到使用者线程正在等待通知。

    pc.list.add(i);
    System.out.println("Producer @work : " + pc.list.size());
    //pcRef.notify();
    
        2
  •  2
  •   Nathan Hughes    6 年前

    synchronized方法计算给定给synchronized块的表达式,以确定要获取什么锁。然后,需要对同一对象调用wait、notify等,但是否使用同一变量无关紧要。代码计算表达式以获取对象。

    现在,thread1是否等待、通知和唤醒取决于比赛条件的结果。如果thread1在thread2调用notify之前进入wait方法,则thread2将等待,然后在thread2通知后唤醒。如果在thread1进入wait方法之前thread2调用notify,则thread1将永远等待。