notify和notifyAll都是java多线程的部分,java提供了机制可以锁住对象(对象也是一种资源),当一个对象被一个线程访问时,这个对象能被锁住,这时其他要访问这个对象的线程就处于阻塞状态。但是如果线程调用了该对象的wait()方法,就会释放该对象的锁,并停止运行继续等待直到其他线程调用了这个对象的notify或notifyALL。但是,可能有好几个线程调用了该对象的wait同时等待,所以notify只是唤醒其中的一个(具体哪一个时由虚拟机的线程调度机制决定的)notifyAll唤醒所有线程。
需要注意的概念是:
# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {…} 代码段内。
-----------------------------------------------------------------------------------------
在什么地方wait()方法、notify()及notifyAll()方法可以被使用?
比如:生产者和消费者共同来操作堆栈吧,消费者从堆中取产品,生产者放产品!
只有当生产者把产品放到了堆中,消费者才可以取到产品,不然就会出错!
当你用两个线程来分别控制生产者和消费者时.他们是同时的.
你可以用wait()方法让消费者那个线程停下来等生产者把产品放到堆里,放完之后,消费者才可以取.
当生产者放完了产品之后,就用notify()通知wait(),让消费者获得运行的权利!
package ProductAndConsume;
import java.util.List;
public class Consume implements Runnable{
private List container = null;
private int count;
public Consume(List lst){
this.container = lst;
}
public void run() {
while(true){
synchronized (container) {
if(container.size()== 0){
try {
container.wait();//放弃锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
container.remove(0);
container.notify();
System.out.println("我吃了"+(++count)+"个");
}
}
}
}
package ProductAndConsume;
import java.util.List;
public class Product implements Runnable {
private List container = null;
private int count;
public Product(List lst) {
this.container = lst;
}
public void run() {
while (true) {
synchronized (container) {
if (container.size() > MultiThread.MAX) {
try {
container.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
container.add(new Object());
container.notify();
System.out.println("我生产了"+(++count)+"个");
}
}
}
}
package ProductAndConsume;
import java.util.ArrayList;
import java.util.List;
public class MultiThread {
private List container = new ArrayList();
public final static int MAX = 5;
public static void main(String args[]){
MultiThread m = new MultiThread();
new Thread(new Consume(m.getContainer())).start();
new Thread(new Product(m.getContainer())).start();
new Thread(new Consume(m.getContainer())).start();
new Thread(new Product(m.getContainer())).start();
}
public List getContainer() {
return container;
}
public void setContainer(List container) {
this.container = container;
}