关于多线程同步的初步教程--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.       catch (InterruptedException ex) {
  10.         notify();
  11.         throw ex;
  12.       }
  13.     }
  14.   }
  15.  
  16.   /** Release a permit **/
  17.   public synchronized void release() {
  18.     ++permits_;
  19.     notify();
  20.   }

这些代码都容易理解,特别需要注意的是新增的release(long n)的方法,

  1.   public synchronized void release(long n) {
  2.     if (n < 0) throw new IllegalArgumentException("Negative argument");
  3.  
  4.     permits_ += n;
  5.     for (long i = 0; i < n; ++i) notify();
  6.   }


其中恢复多个许可,同时,要通过一个循环来notify()其它线程。Simaphore的概念在多线程编程中已经广为熟知,在C++和其它很多语言中也有支持。Doug Lea提供的concurrent包中的Simaphore实现为我们提供了Java中Simaphore的工业强度实现版本,方便了我们在多线程环境中的编程。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值