java多线程之等待通知经典范式

1:运行过程

 

 

  上图所示是两个线程WaitThread和NotifyThread线程的工作状态图,其中WaitThread线程和NotifyThread线程的功能逻辑如下;前者检查flag是否为false,如果符合要去,继续后续操作,如果不满足则继续在Object.wait等待。后者线程,在睡眠了一段时候后,同时通知Object对象上的等待的线程。当然要修改flag符合WaitThread的工作情况。

  上述的工作流程如下;WaitThread线程首先获得对象的锁,然后判断自己的继续运行的flag条件是否满足(while(!flag){  }),如果不满足则调用Object.wait()的方法,从而放弃对象的锁,进入Object对象的等待队列里。由于WaitThread释放了Object对象的锁,所以NotifyThread线程可以获得Object的锁,并修改flag,同时调用Object.notify()方法,然后将WaitThread线程调入同步队列中,将WaitThread的状态有等待变为阻塞。等NotifyThread线程释放锁以后,WaitThread线程再次获得锁并从wait方法返回,然后判断flag,如果满足则进入后续的工作状态。

2:经典范式

  这里总结常用的等待/通知的伪代码,从上面我们总结等待放/通知者的经典范式,分别针对这等待放(消费者)和通知方(生产者)。

2.1:等待方

等待方遵循如下原则

  1. 获取对象的锁。
  2. 如果条件不满足,那么调用对象的wait()方法,进入等待状态。被通知后依然还要检查条件漫步满不满足(这就是要使用while()进行判断的原因,即便从wait方法返回,也要不断地检查条件是否满足)。
  3. 条件满足,则执行对应的逻辑。

对应伪代码如下:

synchronized(对象){
    while(条件不满足){
         对象.wait();
    }
    条件满足的逻辑处理
}

2.2:通知者

通知方遵循如下原则

  1. 获取对象的锁。
  2. 改变条件(flag)
  3. 通知所有在该对象等待的线程。
synchronized(对象){
    改变条件
    对象.notifyAll()
}
posted @ 2020-04-09 09:46  大朱123  阅读(427)  评论(0编辑  收藏  举报