wait-notify机制

wait-notify机制

a.       synchronized方法中的wait方法被调用时,当前线程将被中断运行,并且放弃该对象的锁

b.       一旦线程调用了wait方法,它便进入该对象的等待列表。要从等待列表中删除该线程,使它有机会继续运行,其它线程必须调用同一个对象上的notify或者notifyAll方法

c.       当线程再次成为可运行的线程后,它们便试图重新进入该对象。一旦可以使用该对象锁时,其中的一个线程将锁定该对象,并且从它上次调用wait方法后的位置开始继续运行

 
wait-notify机制
 

实例:

package com.bijian.thread;

public class MyThread extends Thread {

	private Object o;

	MyThread(Object o) {
		this.o = o;
	}

	public void run() {
		synchronized (o) {
			try {
				System.out.println(getName() + " before wait");
				o.wait();
				System.out.println(getName() + " after wait");
			} catch (InterruptedException e) {
			}
		}
	}
}

 

package com.bijian.thread;

public class WaitNotifyAllDemo {

	public static void main(String[] args) {
		Object lock = new Object();
		MyThread mt1 = new MyThread(lock);
		mt1.setName("A");
		MyThread mt2 = new MyThread(lock);
		mt2.setName("B");
		MyThread mt3 = new MyThread(lock);
		mt3.setName("C");
		mt1.start();
		mt2.start();
		mt3.start();
		System.out.println("main thread sleeping");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
		}
		System.out.println("main thread awake");
		synchronized (lock) {
			lock.notifyAll();
		}
	}
}

 

  运行结果:
A before wait
main thread sleeping
B before wait
C before wait
main thread awake
C after wait
B after wait
A after wait

 

实例分析:主线程在打印出“ main thread awake ”之前, A B C 线程应该都已运行至 wait 方法,即 A B C 线程都在 wait 通知队列,当主线程运行完 lock.notifyAll(); 语句后, A B C 线程对象都会从 wait 队列转入 lock 队列,接下来, A B C 线程对象平等竞争锁资源,随机从 lock 队列中取出执行。

 

 

小结:

a.       如果两个或多个线程修改一个对象,请将执行修改的方法声明为synchronized方法。受到对象修改影响的只读方法也必须实现同步。

b.       如果一个线程必须等待某个对象的状态出现变更,那么它应该在对象的内部等待而不是在外面等待。这可以通过进入一个synchronized方法,并且调用wait方法来实现。

c.       不要在synchronized方法中花费大量的时间。大多数操作只是更新数据,然后很快返回。

d.       每当一个方法改变某个对象的状态时,它就应该调用notifyAll方法。这样可以给等待线程一个机会,以便查看环境有没有发生变化。

e.       记住,waitnotifyAll/notify方法都属于Object类的方法,而不是Thread类的方法。反复检查你对wait方法的调用与同一对象上的通知是否匹配。

你可能感兴趣的:(java,thread,java多线程,wait-notify)