信號量Semaphore實現互斥鎖Mutex

字號:

在Doug lea的那本的《Java并發(fā)編程—設計原則與模式》,英文名" Concurrent Programming in Java™: Design Principles and Patterns, Second Edition",書中提到可以用信號量Semaphore實現互斥鎖Mutex。雖然java中是通過synchronize關鍵字提供鎖,并用這個基礎設施實現信號量的。在有的系統(tǒng)中只有信號量這一原語,鎖是通過信號量實現的。代碼如下:
    import java.util.concurrent.Semaphore;
    public class Mutex ...{
     private Semaphore s = new Semaphore(1);
     public void acquire() throws InterruptedException ...{
     s.acquire();
     }
     public void release()...{
     s.release();
     }
     public boolean attempt(int ms) throws InterruptedException ...{
     return s.tryAcquire(ms);
     }
    }
    上面的代碼只能在java5中編譯通過,因為Semaphore是在java5中才提供的。我在讀上面的代碼時有疑問。因為如果錯誤的連續(xù)調用release兩次,然后兩個線程都調用acquire,豈不是這兩個線程都可以同時運行,從而違背了互斥鎖的定義?為了證明我的猜測,寫了如下的代碼:
    public class TestMutex ...{
     public static void main(String[] args) throws InterruptedException...{
     Mutex mutex=new Mutex();
     mutex.acquire();
     mutex.release();
     mutex.release();
     new MyThread(mutex).start();
     new MyThread(mutex).start();
     }
    }
    class MyThread extends Thread...{
     private Mutex mutex;
     public MyThread(Mutex mutex) ...{
     this.mutex=mutex;
     }
     public void run()...{
     try ...{
     mutex.acquire();
     } catch (InterruptedException e1) ...{
     throw new RuntimeException(e1);
     }
     for(int i=0;i<10;i++)...{
     System.out.print(i);
     if(i%3==0)...{
     try ...{
     Thread.sleep(100);
     } catch (InterruptedException e) ...{
     e.printStackTrace();
     }
     }
     }
     mutex.release();
     }
    }
    該程序的輸出如下:
    00123123456456789789
    從而證實了我的猜測。