第14章 构建自定义的同步工具

当使用条件等待时(例如Object.wait或Condition.await):

  • 通常都有一个条件谓词——包括一些对象状态的测试,线程在执行前必须首先通过这些测试。
  • 在调用wait之前测试条件谓词,并且从wait中返回时再次进行测试。
  • 在一个循环中调用wait。
  • 确保使用与条件队列相关的锁来保护构造条件谓词的各个状态变量。
  • 当调用wait、notify或notifyAll等方法时,一定要持有与条件队列相关的锁。
  • 在检查条件谓词之后以及开妈执行相应的操作之前,不要释放锁。

一个Condition和一个Lock关联在一起,就像一个条件队列和一个内置锁相关联一样。要创建一个Condition,可以在相关联的Lock上调用Lock.newCondition方法。正如Lock比内置加锁提供了更为丰富的功能,Condition同样比内置条件队列提供了更丰富的功能:在每个锁上可存在多个等待、条件等待可以是可中断的或不可中断的、基于时限的等待,以及公平的或非公平的队列操作。

特别注意:在Condition对象中,与wait、notify和notifyAll方法对应的分别是await、signal和signalAll。但是,Condition对Object进行了扩展,因而它也包含wait和notify方法。一定要确保使用正确的版本——await和signal。

oneShotLatch也可以通过扩展AQS(AbstractQueuedSynchronizer)来实现,而不是将一些功能委托给AQS,但这种做法并不合理,原因有很多。这样做将破坏OneShotLatch接口(只有两个方法)的简洁性,并且虽然AQS的公共方法不允许调用都破坏闭锁的状态,但调用者仍可以很容易地误用它们。java.util.concurrent中的所有同步器类都没有直接扩展AQS,而是都将它们的相应功能委托给私有的AQS子类来实现。

posted on 2015-10-27 08:30  a0000  阅读(214)  评论(0编辑  收藏  举报

导航