WEB开发网
开发学院WEB开发Jsp Java多线程同步设计中使用Metux 阅读

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

 2008-01-05 20:03:21 来源:WEB开发网   
核心提示:Mutex是互斥体,广泛地应用在多线程编程中,Java多线程同步设计中使用Metux,本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例,进行一点探讨,比如:class X {Sync gate; // ...public void m() {try{gate.acquire();// b


  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();
    try
    {
     for (;;)
     {
      wait(waitTime);
      if (!inuse_)
      {
       inuse_ = true;
       return true;
      }
      else
      {

Tags:Java 线程 同步

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接