代码:
public class NotifyAndWaitTest2 implements Runnable {
public int i = 0;
public Object lock;
public SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
public NotifyAndWaitTest2(Object o) {
this.lock = o;
}
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " enter the SYNCHRONIZED block --- "+ sdf.format(new Date()));
try {
while (i < 9) {
Thread.sleep(500);
lock.notify();
lock.wait();
System.out.println(Thread.currentThread().getName() + " say:" + i++ + " --- " + sdf.format(new Date()));
}
lock.notify();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Object lock = new Object();
NotifyAndWaitTest2 test = new NotifyAndWaitTest2(lock);
Thread t1 = new Thread(test,"Thread A");
Thread t2 = new Thread(test,"Thread B");
Thread t3 = new Thread(test,"Thread C");
Thread t4 = new Thread(test,"Thread D");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
执行结果:
Thread A enter the SYNCHRONIZED block --- 10:47:07.242
Thread B enter the SYNCHRONIZED block --- 10:47:07.743
Thread C enter the SYNCHRONIZED block --- 10:47:08.243
Thread D enter the SYNCHRONIZED block --- 10:47:08.743
Thread C say:0 --- 10:47:09.243
Thread D say:1 --- 10:47:09.744
Thread C say:2 --- 10:47:10.244
Thread D say:3 --- 10:47:10.744
Thread C say:4 --- 10:47:11.245
Thread D say:5 --- 10:47:11.745
Thread C say:6 --- 10:47:12.246
Thread D say:7 --- 10:47:12.746
Thread C say:8 --- 10:47:13.247
Thread D say:9 --- 10:47:13.247
Thread B say:10 --- 10:47:13.247
Thread A say:11 --- 10:47:13.247
这段代码我在 jdk1.7 和 jdk1.8 中都执行过,结果是"相同的"
我主要有两个问题:(以我贴出的这个执行结果为例)
1、在线程A 和线程B 进入了同步代码块之后,并且线程B 调用了 wait() 方法,为什么接下来一定是另外两个线程进入同步代码块?而不是线程A 开始打印 say。是"让新的线程进入同步代码块"的优先级比"调用wait()方法的线程被唤醒"的优先级高吗?
2、为什么调用 notify() 方法只能唤醒最后一个调用了 wait() 方法的线程?就像上面这个执行结果,只有线程C 和线程D 互相唤醒对方,为什么不能唤醒其他的线程,比如线程A 和线程B?
我认为抢对象锁应该是不规律的、随机的,比如这样:
Thread A enter the SYNCHRONIZED block
Thread B enter the SYNCHRONIZED block
Thread A say:0
Thread C enter the SYNCHRONIZED block
Thread B say:1
Thread A say:2
Thread D enter the SYNCHRONIZED block
Thread B say:3
Thread C say:4