首先notify, wait的经典场景是生产者,消费者模型
import org.slf4j.Logger; /** * Created by wcl on 17/9/17. */ public class Consumer implements Runnable { Logger logger = org.slf4j.LoggerFactory.getLogger(Consumer.class); Container container; String name; public Consumer(String name, Container container){ this.name = name; this.container = container; } public void run() { while (true){ synchronized (container){ if (container.count>0){ container.notifyAll(); container.count--; logger.info("消费者{}消费-1,当前数量={}",name, container.count); }else { try { logger.info("消费者{} wait before",name); container.wait(); logger.info("消费者{} wait after",name); } catch (InterruptedException e) { e.printStackTrace(); } } }//sync try { Thread.sleep(140); } catch (InterruptedException e) { e.printStackTrace(); } } } }
/** * Created by wcl on 17/9/17. */ public class Container { int count; int max; public Container(int max){ this.count =0 ; this.max = max; } }
import org.slf4j.Logger; /** * Created by wcl on 17/9/17. */ public class Producer implements Runnable { Logger logger = org.slf4j.LoggerFactory.getLogger(Producer.class); private Container container; private String name; public Producer(String name, Container container){ this.name = name; this.container = container; } public void run() { while (true){ synchronized (container){ if (container.count<container.max){ container.notifyAll(); container.count++; logger.info("生产者{}生产+1,当前数量={}",name, container.count); }else { try { logger.info("生产者{} wait before",name); container.wait(); logger.info("生产者{} wait after",name); } catch (InterruptedException e) { e.printStackTrace(); } } } try { Thread.sleep(100);//调节生产者频率,过快容易猝死~~ } catch (InterruptedException e) { e.printStackTrace(); } } } }
/** * Created by wcl on 17/9/17. */ public class TestProducerConsumer { public static void main(String [] args){ Container container = new Container(5); Producer p1 = new Producer("p1",container); //Producer p2 = new Producer("p2",container); Consumer c1 = new Consumer("c1",container); //Consumer c2 = new Consumer("c2",container); new Thread(p1).start(); //new Thread(p2).start(); new Thread(c1).start(); //new Thread(c2).start(); } }
关于notify,wait有几点需要注意
1. wait()和notify()一系列的方法,是属于对象的,不属于线程。
2.wait()会让出对象锁,同时,当前线程休眠,等待被唤醒,如果不被唤醒,就一直等在那儿。
notify()并不会让当前线程休眠,但会唤醒休眠的线程。
3. wait() 后线程挂起,会释放锁,但是sleep则不会释放锁