Java多線程開發六——鎖、條件變量、信號量

1. 鎖和條件變量
JDK1.5 以上提供了鎖和條件變量來控制線程的同步,想必同步方法和等待 / 通知函數,鎖和條件變量提供了更直觀的使用形式,更廣泛的鎖定操作,更靈活的數據結構。此外,多個條件變量可以和一個鎖綁定。
使用示例,代碼來源於 JDK 文檔,可以看一下基本的用法。
class BoundedBuffer {
   final Lock lock = new ReentrantLock();

   final Condition notFull = lock.newCondition(); 

   final Condition notEmpty = lock.newCondition(); 

 
   final Object[] items = new Object[100];
   int putptr, takeptr, count;
 
   public void put(Object x) throws InterruptedException {
     lock.lock();

     try {

       while (count == items.length) 
         notFull.await();

       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();

     } finally {

       lock.unlock();

     }

   }
 
   public Object take() throws InterruptedException {
     lock.lock();

     try {

       while (count == 0) 
         notEmpty.await();

       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();

       return x;
     } finally {

       lock.unlock();

     }

   } 
 }
 
鎖代替了 synchronized 的使用, Condition 代替了對象監控器方法( wait notify )的使用。
 
2. 信號量
信號量經常用來限制訪問有限資源的線程數量。見一個例子(來源於 JDK 文檔):
 
class Pool {
   private static final MAX_AVAILABLE = 100;
   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
 
   public Object getItem() throws InterruptedException {
     available.acquire();//
獲取許可
     return getNextAvailableItem();
   }
 
   public void putItem(Object x) {
     if (markAsUnused(x))
       available.release();//
釋放許可
   }
 
   // Not a particularly efficient data structure; just for demo
 
   protected Object[] items = ... whatever kinds of items being managed
   protected boolean[] used = new boolean[MAX_AVAILABLE];
 
   protected synchronized Object getNextAvailableItem() {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (!used[i]) {
          used[i] = true;
          return items[i];
       }
     }
     return null; // not reached
   }
 
   protected synchronized boolean markAsUnused(Object item) {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (item == items[i]) {
          if (used[i]) {
            used[i] = false;
            return true;
          } else
            return false;
       }
     }
     return false;
   }
 
 }
例子中最大支持 100 個線程併發訪問,當前 100 個線程沒有釋放許可時,第 101 個線程就只能等待。
以上是簡單的使用說明,如果需要了解更詳細的信息,參考JDK文檔。
 
附:一個用 synchronized wait notify 實現的信號量。

 public   class  Semaphore  {
    
private   int  count;
    
public  Semaphore( int  count) {
        
this .count = count;
    }

    
synchronized   public   void  acquire()  { // throws InterruptedException{
         while  (count == 0 ) {
            
try   {
                wait();
            }
  catch  (InterruptedException e)  {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        count 
-- ;
    }

    
synchronized   public   void  release() {
        count 
++ ;
        notify();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章