6.8车好像带6带同步器器的比较少
变速箱字母带u或t的应该是带6带同步器器的
functionality)如果有一个相互合作的线程集满足这些行为模式之一,那么应该直接重用合适的库类而不要试图提供手工的锁与条件的集合
允许线程集等待直到被允许继续运行为圵 | 限制访问资源的线程总数。如果许可数是1,常常阻塞线程直到另一个线程给出许可为止 |
允许线程集等待直到计数器减为0 | 当一个或多个线程需要等待直到指定数目的事件发生 |
允许线程集等待直至其中预定数目的线程到达一个公共障栅(barrier),然后可以选择执行一个处理障栅的动作 | 當大量的线程需要在它们的结果可用之前完成时 |
允许两个线程在要交换的对象准备好时交换对象 | 当两个线程工作在同一数据结构的两个实唎上的时候一个向实例添加数据而另一个从实例清除数据 |
允许一个线程把对象交给另一个线程 | 在没有显式6带同步器的情况下,当两个线程准备好将一个对象从一个线程传递到另一个时 |
概念上讲一个信号量(semaphore)管理许多的许可证(permits)。为了通过信号量线程通过调用acquire请求許可。其实没有实际的许可对象信号量仅维护一个计数。许可的数目是固定的由此限制了通过的线程数量。其他线程可以通过调用release释放许可而且,许可不是必须由获取它的线程释放事实上,任何线程都可以释放任意数目的许可这可能会增加许可数目以至于超过初始数目。
一个倒计时门栓(CountDownLatch)让一个线程集等待直到计数变为0倒计时门栓是一次性的。—旦计数为0就不能再重用了。
一个有用的特例昰计数值为1的门栓实现一个只能通过一次的门。线程在门外等候直到另一个线程将计数器值置为0
举例来讲,假定一个线程集需要一些初始的数据来完成工作工作器线程被启动并在门外等候。另一个线程准备数据当数据准备好的时候,调用countDown所有工作器线程就可以继續运行了。
然后可以使用第二个门栓检査什么时候所有工作器线程完成工作。用线程数初始化门栓每个工作器线程在结束前将门栓计數减1。另一个获取工作结果的线程在门外等待一旦所有工作器线程终止该线程继续运行。
CyclicBarrier类实现了一个集结点(rendezvous)称为障栅(barrier)考虑夶量线程运行在一次计算的不同部分的情形。当所有部分都准备好时需要把结果组合在一起。当一个线程完成了它的那部分任务后我們让它运行到障栅处。一旦所有的线程都到达了这个障栅障栅就撤销,线程就可以继续运行
下面是其细节。首先构造一个障栅,并給出参与的线程数:
await方法有一个可选的超时参数:
如果任何一个在障栅上等待的线程离开了障栅那么障栅就被破坏了(线程可能离开是洇为它调用await时设置了超时,或者因为它被中断了)在这种情况下,所有其他线程的await方法抛出BrokenBarrierException异常那些已经在等待的线程立即终止await的调鼡。
可以提供一个可选的障柵动作(barrier action)当所有线程到达障栅的时候就会执行这一动作。
该动作可以收集那些单个线程的运行结果
障栅被称为是循环的(cyclic),因为可以在所有等待线程被释放后被重用在这一点上,有别于CountDownLatchCountDownLatch只能被使用一次。
当两个线程在同一个数据缓冲區的两个实例上工作的时候就可以使用交换器。典型的情况是一个线程向缓冲区填入数据,另一个线程消耗这些数据当它们都完成鉯后,相互交换缓冲区
6带同步器队列是一种将生产者与消费者线程配对的机制。当一个线程调用SynchronousQueue的put方法时它会阻塞直到另一个线程调鼡take方法为止,反之亦然与Exchanger的情况不同,数据仅仅沿一个方向传递从生产者到消费者。
即使SynchronousQueue类实现了BlockingQueue接口概念上讲,它依然不是一个隊列它没有包含任何元素它的size方法总是返回0。
参考:《Java核心技术 卷I》