注意点:
1、notify和wait调用的时候必须先获取对象的锁,所以必须放在同步代码块里面,比如:
synchronized (xx) {
xx.wait();|xx.notify//不要在此同时调用,不然会造成死锁。
}
2、即使调用了nodify方法,也不会立即执行该线程的代码快,要等当前线程释放了该锁(已经跳出同步代码块<synchronized>,此时会和nodify的线程竞争对象锁)或执行了wait()方法主动释放。
以下是经典的生产者与消费者模型。
package test; import java.util.ArrayList; import java.util.List; public class scAndxf { private static List container = new ArrayList(); public static void main(String[] args) { new Thread(new xf(container)).start(); new Thread(new sc(container)).start(); } } class xf implements Runnable{ private List container = null; private int count; public xf(List l){ container=l; } @Override public void run() { while(true){ synchronized (container) { if(container.size()==0){ try { container.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } container.remove(0); container.notify(); System.out.println("我吃了"+(++count)+"个"); } } // TODO Auto-generated method stub } } class sc implements Runnable{ private List container = null; private int count; public sc(List lst) { this.container = lst; } @Override public void run() { // TODO Auto-generated method stub synchronized (container) { while (true) { if (container.size() > 5) { //如果容器超过了最大值,就不要在生产了,等待消费 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)+"个"); } } } }
打印结果为:
我生产了1个
我生产了2个
我生产了3个
我生产了4个
我生产了5个
我生产了6个
我吃了1个
我生产了7个
我吃了2个
我生产了8个
我吃了3个
我生产了9个
我吃了4个
我生产了10个
我吃了5个
我生产了11个
我吃了6个
我生产了12个
我吃了7个
我生产了13个
我吃了8个
我吃了9个
我生产了14个
我生产了15个
我吃了10个
我生产了16个
我吃了11个
我生产了17个
我吃了12个
我吃了13个
我生产了18个
我生产了19个
我吃了14个
我生产了20个
我吃了15个
我生产了21个
我吃了16个