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

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

    在前面的“关于多线程同步的初步教程--Metux的设计及使用”一文中,我们讨论了Doug Lea的concurrent包的Mutux的设计及实现,本文讨论一下多线程编程中同样常用的Simaphore的设计和使用。Simaphore也继承于Sync接口,和Mutex相比,Simaphore增加了同步的计数支持。一个Simaphore,代表了多个许可,可以一次获取多个许可,也可以一次释放多个许可。如果将Simaphore的许可数减少到1,那么就可以作为一个Mutex使用了。下面的代码演示了Simaphore的基本使用:

  1.  class Pool {
  2.     static final MAX_AVAILABLE = 100; // 100个许可
  3.     private final Semaphore available = new Semaphore(MAX_AVAILABLE);
  4.     
  5.     public Object getItem() throws InterruptedException { // no synch
  6.       available.acquire();
  7.       return getNextAvailableItem();
  8.     }
  9.  
  10.     public void putItem(Object x) { // no synch
  11.       if (markAsUnused(x))
  12.         available.release();
  13.     }
  14.  
  15.    // Not a particularly efficient data structure; just for demo
  16.  
  17.     protected Object[] items = ... whatever kinds of items being managed
  18.     protected boolean[] used = new boolean[MAX_AVAILABLE];
  19.  
  20.     protected synchronized Object getNextAvailableItem() { 
  21.       for (int i = 0; i < MAX_AVAILABLE; ++i) {
  22.         if (!used[i]) {
  23.            used[i] = true;
  24.            return items[i];
  25.         }
  26.       }
  27.       return null; // not reached 
  28.     }
  29.  
  30.     protected synchronized boolean markAsUnused(Object item) { 
  31.       for (int i = 0; i < MAX_AVAILABLE; ++i) {
  32.         if (item == items[i]) {
  33.            if (used[i]) {
  34.              used[i] = false;
  35.              return true;
  36.            }
  37.            else
  38.              return false;
  39.         }
  40.       }
  41.       return false;
  42.     }
  43.  
  44.   }

可见,Simaphore是对Mutex的增强,Simaphore也和Mutex相比,增加了如下的方法:

1、public Semaphore(long initialPermits)
构造函数,指定许可的数量。
2、public synchronized long permits()
返回许可的数量。
3、public synchronized void release(long n)
一次释放n个许可。

相应的,在Simaphore的实现中,也增加了一个字段,存储许可的数量:
protected long permits_;

acquire和release方法也有相应的变化:

  1.   /** Wait until a permit is available, and take one **/
  2.   public void acquire() throws InterruptedException {
  3.     if (Thread.interrupted()) throw new InterruptedException();
  4.     synchronized(this) {
  5.       try {
  6.         while (permits_ <= 0) wait();
  7.         --permits_;
  8.       }
  9. &nb
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,