監視器 (程序同步化)
條件變數(Condition Variable) > 阻塞式条件变量

东尼·霍尔与泊·派克·汉森最早提出的是阻塞式条件变量. 发出通知(signaling)的线程必须等待被通知(signaled)的线程放弃占用管程（或者离开管程，或者等待某个条件变量）。使用阻塞式条件变量的管程被称为霍尔风格(Hoare-style)管程或通知且急迫等待(signal-and-urgent-wait)管程.
设每个管程对象有两个线程队列
e是入口队列
s是已经发出通知的线程队列.
设对于每个条件变量 c, 有一个线程队列
c.q, 所有等待 c的线程的队列
这些队列会公平(fair)调度，甚至实现为先进先出.
各个环节实现如下 (规定各个环节彼此是互斥的. 因此restart一个线程，并不会立即执行，直到当前环节完成)
enter the monitor:
    enter the method
    if the monitor is locked
        add this thread to e
        block this thread
    else
        lock the monitor
leave the monitor:
    schedule
    return from the method
wait  c :
    add this thread to  c.q
    schedule
    block this thread
signal  c :
    if there is a thread waiting on  c.q
        select and remove one such thread t from  c.q
        (t is called "the signaled thread")
        add this thread to s
        restart t
        (so t will occupy the monitor next)
        block this thread
schedule :
    if there is a thread on s
      select and remove one thread from s and restart it
      (this thread will occupy the monitor next)
    else if there is a thread on e
      select and remove one thread from e and restart it
      (this thread will occupy the monitor next)
    else
      unlock the monitor
      (the monitor will become unoccupied)
schedule子程序选择下一个线程占用管程，如果没有候选的线程则解锁管程.
发出通知的线程转入等待，但会比在线程入口的队列有更高优先权被调度，这称为"通知且急迫等待"。另一种方案是"通知且等待"，不设s队列，发出通知的线程进入e队列等待.
某些实现提供了signal and return操作.
signal  c and return :
    if there is a thread waiting on  c.q
        select and remove one such thread t from  c.q
        (t is called "the signaled thread")
        restart t
        (so t will occupy the monitor next)
    else
        schedule
    return from the method
如果在每个signal  c的开始处， P_{c}为真, 那么在wait  c的结尾处 P_{c}也应为真。 这可由契约式设计来表达. 在这些契约中,  I是管程的不变量.
enter the monitor:
    postcondition  I
leave the monitor:
    precondition  I
wait  c :
    precondition  I
    modifies the state of the monitor
    postcondition  P_{c} and  I
signal  c :
    precondition  P_{c} and  I
    modifies the state of the monitor
    postcondition  I
signal  c and return :
    precondition  P_{c} and  I
在上述契约中，设定 I and  P_{c}不依赖于任何队列长度.
如果可以查询条件变量所关联的队列上处于等待的线程的数量，可以使用更为复杂的契约。例如，一个有用的契约对，无需不变量就允许管程的占用被传递
wait  c :
    precondition  I
    modifies the state of the monitor
    postcondition  P_{c}
signal  c
    precondition (not empty( c) and  P_{c}) or (empty( c) and  I)
    modifies the state of the monitor
    postcondition  I
参见
Howard
and
Buhr et al.,有更多信息。
特别需要注意，断言 P_{c}完全是由编程者负责，编程者需要在头脑中保持对断言有一致的(consistent)定义。
下例是用阻塞式管程实现一个有界的、线程安全的栈. 即多线程并发访问这个栈时，在任意时刻最多只有一个线程执行push或pop操作。
monitor class SharedStack {
  private const capacity := 10
  private int[capacity] A
  private int size := 0
  invariant 0 <= size and size <= capacity
  private BlockingCondition theStackIsNotEmpty /* associated with 0 < size and size <= capacity */
  private BlockingCondition theStackIsNotFull /* associated with 0 <= size and size < capacity */
public method push(int value)
  {
    if size = capacity then wait theStackIsNotFull
    assert 0 <= size and size < capacity
    A[size] := value ; size := size + 1
    assert 0 < size and size <= capacity
    signal theStackIsNotEmpty and return
  }
public method int pop()
  {
    if size = 0 then wait theStackIsNotEmpty
    assert 0 < size and size <= capacity
    size := size - 1 ;
    assert 0 <= size and size < capacity
    signal theStackIsNotFull  and return A[size]
  }
}