通知All()调用时的恢复顺序是什么


static Integer sync = 1;
static void m() throws Exception {
    synchronized (sync) {
        System.out.println(Thread.currentThread().getName());
        sync.wait(1000L);
        System.out.println(Thread.currentThread().getName());
    }
}
static void mthd() throws Exception {
    synchronized (sync) {
        System.out.println("Notifying...");
        sync.notify();
    }
}
public static void main(String[] args) throws Exception {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            try {
                m();
            } catch (Exception ex) {
                Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    };
    Runnable t = new Runnable() {
        @Override
        public void run() {
            try {
                m();
            } catch (Exception ex) {
                Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    };
    Runnable g = new Runnable() {
        @Override
        public void run() {
            try {
                mthd();

    } catch (Exception ex) {
                Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    };
    Thread th1 = new Thread(r);
    Thread th2 = new Thread(t);
    Thread th3 = new Thread(g);
    th1.start();
    th2.start();
    th3.start();
}

该代码生成以下输出:

Thread-0
Thread-1
Notifying...
Thread-0
Thread-1

也就是说,我们的顺序与添加到等待集的顺序相同,或者它没有指定?

未指定通知顺序,因此此时任何线程都可以执行。这完全取决于线程调度程序何时应该执行每个调度程序。

来自 notify(( 文档:

如果有任何线程正在等待此对象,则选择其中一个线程进行唤醒。选择是任意的,由实现自行决定。

并通知所有((文档:

唤醒的线程

将以通常的方式与可能主动竞争以在此对象上进行同步的任何其他线程竞争;例如,唤醒的线程在成为下一个锁定此对象的线程时没有可靠的特权或劣势。

因此,不仅等待线程不会按顺序唤醒,以前没有等待但出于其他原因(例如,调用 synchronized 方法(想要锁的线程可能会首先获得锁。

最新更新