Mutex是互斥体广泛地应用在多线程编程中本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例进行一点探讨在Doug Lea的concurrent工具包中Mutex实现了Sync接口该接口是concurrent工具包中所有锁(lock)门(gate)和条件变量(condition)的公共接口Sync的实现类主要有MutexSemaphore及其子类LatchCountDownReentrantLock等这也体现了面向抽象编程的思想使我们可以在不改变代码或者改变少量代码的情况下选择使用Sync的不同实现下面是Sync接口的定义
public interface Sync
{
public void acquire() throws InterruptedException;
//获取许可
public boolean attempt(long msecs) throws InterruptedException;
//尝试获取许可
public void release();
//释放许可
}
通过使用Sync可以替代Java synchronized关键字并提供更加灵活的同步控制当然并不是说 concurrent工具包是和Java synchronized独立的技术其实concurrent工具包也是在synchronized的基础上搭建的从下面对Mutex源码的解析即可以看到这一点synchronized关键字仅在方法内或者代码块内有效而使用Sync却可以跨越方法甚至通过在对象之间传递跨越对象进行同步这是Sync及concurrent工具包比直接使用synchronized更加强大的地方
注意Sync中的acquire()和attempt()都会抛出InterruptedException所以使用Sync及其子类时调用这些方法一定要捕获InterruptedException而release()方法并不会抛出InterruptedException这是因为在acquire()和attempt()方法中可能会调用wait()等待其它线程释放锁而release()在实现上进行了简化直接释放锁不管是否真的持有所以你可以对一个并没有acquire()的线程调用release()这也不会有什么问题而由于release()不会抛出InterruptedException所以我们可以在catch或finally子句中调用release()以保证获得的锁能够被正确释放比如
class X
{
Sync gate; //
public void m()
{
try
{
gateacquire();
// block until condition holds
try
{
// method body
}
finally { gaterelease(); }
}
catch (InterruptedException ex) { // evasive action }
}
}
[] [] []