正文
Guarded 是被守护,被保卫,被保护的意思, Suspension 则是暂停的意思.如果执行现在的处理会出现问题,就让处理问题的线程进行等待–这就是 Guarded Suspension 模式
利用 LinkedList 实现 LinkedBlockingQueue?
下面整个 MyBlockQueue api 就是利用了整个模式,当队列为空时,就让 调用 take 的线程一直等待,直到调用 put 后再唤醒
1 | package com.creambing.concurrent.chapterthree; |
wait和锁的关系
调用 wait 的时候必须先获取锁
我们先说明一下等待队列,当调用 wait() 方法时,该线程就会放入等待队列中,并同时释放在进入 wait() 方法之前获取的锁
所有实例都拥有一个等待队列,它是在实例的 wait 方法执行后停止操作的线程的队列,打个比方来说,就是为每个实例准备的线程休息室
在执行 wait 方法后,线程便会暂停操作,进入等待队列这个休息室.除非发生下列某一情况,否则线程便会一直在等待队列中休眠.当下列任意一种情况发生时,线程便会退出等待队列
1 | 有其他线程的 notify 方法来唤醒线程 |
如果 wait 和 notifyAll 需要放在 synchronized 代码块中需要如何改造?
1 | // 线程 A 的代码 |
因为调用 wait() 会挂起该线程同时释放锁,因为 synchronized 代码块中 obj_A 可以时任意对象,所以需要调用该对象的 wait 和 notifyAll 方法
当调用 notifyAll 方法时,此时锁还在 notifyAll 线程上,它并不像 wait 调用后会直接释放锁,它只是通知那些等待队列中的线程,可以退出等待,出来竞争锁了,此时如果 notifyAll 的线程执行完锁中的代码,释放锁之后,那些线程谁获取到锁就继续执行下去
同 wait 方法一样,若要执行 notify 或者 notifyAll 方法,线程必须持有要调用实例的锁