在Java中,可以调用wait()方法使当前线程进入object的等待队列,这样当有新的任务需要执行的时候,调用object的notify()或者notifyAll()方法就可以唤起线程,wait(),notify()在线程池、数据库连接池有有广泛的应用。
其流程为:
首先我们知道,在获取对象的锁,也就是获取到其监视器,获取锁成功之后,则线程进入 RUNNABLE状态,即运行状态,这时候如果调用其对象的wait()方法,即进入对象的等待队列,然后会将锁释放。这时候,别的线程可以获取到这个对象的锁,然后调用其 notifyAll() 方法,这样,所有在等待队列中的线程(即 WAITING 状态)都会进入这个线程的 同步队列,即锁队列。注意 ,调用 notifyAll() 方法 的线程此时可能还并没有释放锁。必须等这个线程释放锁之后,同步队列中的线程才可以一个一个的执行(同步队列中的线程获取到锁之后,必须执行完同步代码块,才会释放锁),也就是说,wait()之后进入到等待队列,notifyAll()后进入锁队列,但只有重新获取到锁之后才能从wait()方法返回,但当wait()的时候线程被打断呢?其实打断的时候,线程也是进入到了锁队列,跟上述一样,而只有当重新获取到锁之后,才会走catch(Execption)的代码块,而不是从wait()方法返回。
有人可能要说了?为什么要这么设计?为什么notify()之后能不能马上从wait()方法返回?为什么还要等再次获取到锁的时候才能返回???
因为只有这样,才能保证在多个线程都在执行Object的同步块的时候:
synchronized (Object) {
}
同一时间,只有一个线程在 synchronized 代码块中!其它的线程要么在Object的等待队列中,要么就是在锁队列中!这样就避免了多个线程在同步块中执行导致的同步问题。
下面举示例来说明:
一、wait()方法与notify()方法
两个等待线程WaitRunnable,一个唤起线程 NotifyAllRunnable,两个等待线程WaitRunnable 等待一段时间之后,唤起线程 NotifyAllRunnable运行,然后调用 NotifyAll方法,然后等待一段