(注意) t1.wait(); // 不是使t1线程等待,而是让拥有t1这个对象的主线程等待
package test;
public class WaitTest2 {
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
synchronized(t1) {
try {
// 启动“线程t1”
System.out.println(Thread.currentThread().getName()+" start t1");
t1.start();
// 主线程等待t1通过notify()唤醒。
System.out.println("挂起主线程");
System.out.println("线程t1的状态是:"+t1.isAlive());
t1.wait(); // 不是使t1线程等待,而是让拥有t1这个对象的主线程等待
System.out.println("挂起主线程后面的输出");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ThreadA extends Thread{
public ThreadA(String name) {
super(name);
}
public void run() {
synchronized (this) {
try {
Thread.sleep(1000); // 使当前线阻塞 1 s确保在主线程wait()之前t1没有执行完并退出
} catch (Exception e) {
e.printStackTrace();
}
//System.out.println(Thread.currentThread().getName()+" call notify()");
// 唤醒当前的wait线程
//this.notify();
}
}
}
main start t1
挂起主线程
线程t1的状态是:true
挂起主线程后面的输出
在上面的例子中,同样是把notify()这个方法注释掉了,但是主线程wait()后面的代码还是可以得到执行,这说明了t1.wait()运行后,不需要t1.notify()能够唤醒!
线程正常结束后,会使以这个线程对象运行的wait()等待,退出等待状态!而如果在运行wait()之前,线程已经结束了,则这个wait就没有程序唤醒了,例如如果上述不睡1秒的话,在主线程的t1.wait()执行之前就运行完毕退出那么主线程就无法被唤醒了。
实际上,Thread源码里面的join()方法也是使用这种机制:
原码里的join()方法,实际上就是运行的 wait(). 需要运行join的线程运行join方法,实际上是在此线程上调用了需要加入的线程对象的wait()方法,加入的线程运行完后,自然从wait退出了。
结论:
线程对象的wait()方法运行后,可以不用其notify()方法退出,会在线程结束后,自动退出。
线程通信.JPG
while(true) {
synchronized (r) {
if(!r.flag) {
try {
r.wait(); //虽然wait()是object的方法,任何它的子类都可以调用,但是此处还是要 用 共有资源的对象来调用
} catch (Exception e) {
}
}
System.out.println(r.name+""+r.sex+"");
r.flag=true;
r.notify();}
}