快速业务通道

Java多线程同步设计中使用Metux - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-07-04

Java多线程同步设计中使用Metux

时间:2007-11-05

Mutex是互斥体,广泛地应用在多线程编程中。本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例,进行一点探讨。在Doug Lea的concurrent工具包中,Mutex实现了Sync接口,该接口是concurrent工具包中所有锁(lock)、门(gate)和条件变量(condition)的公共接口,Sync的实现类主要有:Mutex、Semaphore及其子类、Latch、CountDown、ReentrantLock等。这也体现了面向抽象编程的思想,使我们可以在不改变代码或者改变少量代码的情况下,选择使用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   {    gate.acquire();    // block until condition holds    try    {     // ... method body    }    finally { gate.release(); }   }   catch (InterruptedException ex) { // ... evasive action }  }}

Mutex是一个非重入的互斥锁。Mutex广泛地用在需要跨越方法的before/after类型的同步环境中。下面是Doug Lea的concurrent工具包中的Mutex的实现。

public class Mutex implements Sync{  /** The lock status **/  protected boolean inuse_ = false;  public void acquire() throws InterruptedException  {   if (Thread.interrupted()) throw new InterruptedException();//(1)   synchronized(this)   {    try    {     while (inuse_) wait();     inuse_ = true;    }    catch (InterruptedException ex)    {     //(2)     notify();     throw ex;    }   }  }  public synchronized void release()  {   inuse_ = false;   notify();  }  public boolean attempt(long msecs) throws InterruptedException  {   if (Thread.interrupted()) throw new InterruptedException();   synchronized(this)   {    if (!inuse_)    {     inuse_ = true;     return true;    }    else if (msecs <= 0)     return false;    else    {     long waitTime = msecs;     long start = System.currentTimeMillis();     tr

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号