java线程学习(四):线程等待wait()和通知notify()的详细使用

线程等待wait()和通知notify(),主要用于多线程之间的协作,而且这两个方法都是属于Object类,说明任何对象都可以调用这两个方法。

当在一个对象实例上调用wait()方法后,当前线程就会在这个对象上等待。直到另外的线程调用了notify()方法,出于等待的线程才得以继续进行。这样,多线程之间的协作就可以用这两个方法进行通信了。

先看下例子:

package stop_demo;

public class Wait_notify_demo {
	final static Object object=new Object();
	final static Object object2=new Object();
	public static class T1 extends Thread{
		public void run(){
			synchronized (object) {
				System.out.println(System.currentTimeMillis()+" :T1 启动!");
				try {
					System.out.println(System.currentTimeMillis()+" :T1等待object锁。。。。。");
					object.wait();
					System.out.println("object被唤醒。。。");
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println(System.currentTimeMillis()+" T1 end");

			}
		}
	}
		public static class T2 extends Thread{
			public void run(){
				synchronized (object) {
					System.out.println(System.currentTimeMillis()+" :T2 start! 随机通知一条线程。");
					object.notify();//要object实例调用notify才行
					System.out.println(System.currentTimeMillis()+" T2 end");
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	public static void main(String[] args) {
		Thread t1=new T1();
		Thread t2=new T2();
		t1.start();
		t2.start();
	}
}

输出结果:
在这里插入图片描述

可以看到,t1线程启动后,进入等待状态,t2线程运行,当执行object.notify()时,通知等待队列中的线程启动,也就是t1启动,然后继续往下执行。

多运行几次,就会发现有时候输出这样的:
在这里插入图片描述
原因是T2先运行,结果t1运行后,执行wait方法而处于一直等待状态,因为没有其他线程去唤醒t1线程。

不过应该注意的是:

  • wait() 和 notify()必须配合synchrozied关键字使用,无论是wait()还是notify()都需要首先获取目标对象的一个监听器。

  • wait()会释放锁,而notify()不释放锁。

wait()会释放锁,而notify()不释放锁,这个是怎么理解呢?其实看第一个输出截图就可以知道,当t1运行到wait方法时,如果t1没有释放锁,那么t2线程压根就无法运行下去,说明wait()会释放锁,而当运行到t2中的notify时,t2会在当前线程往下执行,执行完了才让t1继续执行,说明notify方法并没有把锁释放了。

猜你喜欢

转载自blog.csdn.net/shenhaiyushitiaoyu/article/details/85050153