`
softstone
  • 浏览: 460892 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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代替了对象监控器方法(waitnotify)的使用。
 
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文档。
 
附:一个用synchronizedwaitnotify实现的信号量。
 
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