当前位置:编程学习 > JAVA >>

关于多线程同步的初步教程--Metux的设计及使用

    Mutex是互斥体,广泛地应用在多线程编程中。本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例,进行一点探讨。在Doug Lea的concurrent工具包中,Mutex实现了Sync接口,该接口是concurrent工具包中所有锁(lock)、门(gate)和条件变量(condition)的公共接口,Sync的实现类主要有:Mutex、Semaphore及其子类、Latch、CountDown、ReentrantLock等。这也体现了面向抽象编程的思想,使我们可以在不改变代码或者改变少量代码的情况下,选择使用Sync的不同实现。下面是Sync接口的定义:

  1. public inte易做图ce Sync {
  2.   public void acquire() throws InterruptedException//获取许可
  3.   public boolean attempt(long msecs) throws InterruptedException//尝试获取许可
  4.   public void release(); //释放许可
  5. }

通过使用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()以保证获得的锁能够被正确释放。比如:

  1. class X {
  2.    Sync gate;
  3.    // ...
  4.    public void m() { 
  5.      try {
  6.        gate.acquire();  // block until condition holds
  7.        try {
  8.          // ... method body
  9.        }
  10.        finally {
  11.          gate.release();
  12.        }
  13.      }
  14.      catch (InterruptedException ex) {
  15.        // ... evasive action
  16.      }
  17.    }
  18. }



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

  1. public class Mutex implements Sync  {
  2.   /** The lock status **/
  3.   protected boolean inuse_ = false;
  4.   public void acquire() throws InterruptedException {
  5.     if (Thread.interrupted()) throw new InterruptedException(); //(1)
  6.     synchronized(this) {
  7.       try {
  8.         while (inuse_) wait(); 
  9.         inuse_ = true;
  10.       }
  11.       catch (InterruptedException ex) { //(2)
  12.         notify();
  13.         throw ex;
  14.       }
  15.     }
  16.   }
  17.   public synchronized void release()  {
  18.     inuse_ = false;
  19.     notify(); 
  20.   }
  21.   public boolean attempt(long msecs) throws InterruptedException {
  22.     if (Thread.interrupted()) throw new InterruptedException();
  23.     synchronized(this
补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,