public class 等待和通知 {
final static Object ob=new Object();
public static class T1 extends Thread{
@Override
public void run() {
synchronized (ob){
System.out.println("t1-----------我现在正在等待执行");
try {
Thread.sleep(2000);
ob.wait();
System.out.println("t1-----------我要开始了");
Thread.sleep(3000);
System.out.println("t1-----------我执行结束了,唤醒t2");
ob.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static class T2 extends Thread{
@Override
public void run() {
synchronized (ob){
System.out.println("t2-----------我现在执行");
try {
Thread.sleep(1000);
System.out.println("t2-----------我释放了执行权");
ob.notify();
System.out.println("t2-----------我再次拿到了执行权,开始执行");
Thread.sleep(5000);
System.out.println("t2-----------我等着t1执行之后在执行");
ob.wait();
System.out.println("t2-----------我彻底结束了");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread t1=new T1();
Thread t2=new T2();
t1.start();
t2.start();
/*执行步骤
t1先执行,然后阻塞此线程,等待唤醒
t2获取ob 开始执行,唤醒等待的线程中的一个,其他线程必须等待它执行结束之后才可以执行
t1再次拿到执行权,执行
* */
/*wait():
等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。
调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。
notify():
唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
notifyAll():
唤醒所有等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。*/
}
}