notifyAll()调用时恢复顺序是什么?

时间:2014-09-07 13:39:12

标签: java types

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

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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

来自notify() documentation

  

如果有任何线程在等待这个对象,则选择其中一个线程被唤醒。选择是任意的,由实施决定。

notifyAll() documentation

  

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

因此,不仅等待线程没有按顺序唤醒,一个先前没有等待但由于另一个原因而想要锁定的线程(比如调用synchronized方法)可能首先获得锁定。