`
zscomehuyue
  • 浏览: 402504 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java多线程开发六——锁、条件变量、信号量 收藏

阅读更多
原创  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();
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics