首先我们来看一张图,这张图描述了线程操作的几个步骤。




notifyItemRemoved 动效问题 notify to do_System


图已经描述的很清楚了,这里除了wait()之外,其他的前面都已经接触过了。


这一章我们主要来说一下和wait()相关的操作,其实和wait()相关的还有另外两个函数notity()和notifyAll()。


这三个函数都是Object类里的方法


wait():使调用此方法的线程释放共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒


notify():随机唤醒等待队列中等待同一个共享资源的“一个”线程,并使该线程退出等待队列,进入可运行状态,也就是说notofy()通知唤醒一个线程。


等待队列中等待同一个共享资源的“全部”线程从等待状态退出,进入可运行状态。


注意: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

  1. .
  2. .
  3. .


可见生产者和消费者是交替执行的。


这里仅仅是单生产者和消费者。如果是多生产者和消费者会正常运行吗?


答案是否定的。因为notify()之后是随机唤醒一个线程,如果生产者唤醒的是生产者,那么就会一直处于wait(),造成死锁。


解决问题的方法:


    将notify()方法换成notifyAll()