首先我们来看一张图,这张图描述了线程操作的几个步骤。
图已经描述的很清楚了,这里除了wait()之外,其他的前面都已经接触过了。 这一章我们主要来说一下和wait()相关的操作,其实和wait()相关的还有另外两个函数notity()和notifyAll()。 这三个函数都是Object类里的方法 wait():使调用此方法的线程释放共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒 notify():随机唤醒等待队列中等待同一个共享资源的“一个”线程,并使该线程退出等待队列,进入可运行状态,也就是说notofy()通知唤醒一个线程。 notifyAll():使所有正在 等待队列中等待同一个共享资源的“全部”线程从等待状态退出,进入可运行状态。 注意:notify()和notifyAll()后并不是直接就释放锁的,而是等notify()后的代码执行完毕后才释放锁。而且这三个方法都必须在synchronize代码块里执行,否则会报错。 每个对象都有两个队列,一个是就绪队列,一个是阻塞队列。就绪队列存储了将要获得锁的线程,阻塞队列存储了所有被阻塞的线程。一个线程被唤醒后,才会进入就绪队列,等待CPU的调度,反之,一个线程被wait()之后,线程就进入了阻塞队列,等待下一次被唤醒。 线程会释放锁的三种情况: 1.线程任务执行完毕,释放锁。 2.线程调用wait()方法,释放锁。 3.线程执行过程中发生异常,释放锁。 生产-消费者模式: 单生产者,单消费者demo: ①.生产者: package com.multiThread.bean;publicclass P {privateObject lock;public P(Object lock){this.lock = lock;}publicvoidSetValue(){try{synchronized(lock){if(!ValueObject.value.equals("")){ lock.wait();}String value =System.currentTimeMillis()+"_"+System.nanoTime();System.out.println("set值为:"+ value);ValueObject.value = value; lock.notify();}}catch(Exception e){ e.printStackTrace();}}} ②.消费者 package com.multiThread.bean;publicclass C {privateObject lock;public C(Object lock){this.lock = lock;}publicvoid getValue(){try{synchronized(lock){if(ValueObject.value.equals("")){ lock.wait();}System.out.println("get的值:"+ValueObject.value);ValueObject.value =""; lock.notify();}}catch(Exception e){ e.printStackTrace();}}} ③.生产者线程类 package com.multiThread.thread;import com.multiThread.bean.P;publicclassThreadPimplementsRunnable{private P p;publicThreadP(P p){this.p = p;}@Overridepublicvoid run(){while(true){ p.SetValue();}}} ④.消费者线程类 package com.multiThread.thread;import com.multiThread.bean.C;publicclassThreadCimplementsRunnable{private C c;publicThreadC(C c){this.c = c;}@Overridepublicvoid run(){while(true){ c.getValue();}}} ⑤.测试类 package com.multiThread.test.productionConsumption;import com.multiThread.bean.C;import com.multiThread.bean.P;import com.multiThread.thread.ThreadC;import com.multiThread.thread.ThreadP;/** * 等待、通知机制 */publicclassProduceCustomTest{publicstaticvoid main(String[] args){Object lock =newObject(); P p =new P(lock); C c =new C(lock);ThreadP tp =newThreadP(p);ThreadC tc =newThreadC(c);Thread t1 =newThread(tp);Thread t2 =newThread(tc); t1.start(); t2.start();}} 执行结果: set值为:1466176983137_22743411842275get的值:1466176983137_22743411842275set值为:1466176983137_22743412731096get的值:1466176983137_22743412731096set值为:1466176983137_22743412952232get的值:1466176983137_22743412952232set值为:1466176983137_22743413140860get的值:1466176983137_22743413140860... 可见生产者和消费者是交替执行的。 这里仅仅是单生产者和消费者。如果是多生产者和消费者会正常运行吗? 答案是否定的。因为notify()之后是随机唤醒一个线程,如果生产者唤醒的是生产者,那么就会一直处于wait(),造成死锁。 解决问题的方法: 将notify()方法换成notifyAll() 来自为知笔记(Wiz)转载于:https://www.cnblogs.com/douJiangYouTiao888/p/6473809.html