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

本文介绍了Java 1.5及以上版本提供的锁和条件变量机制,通过示例展示了如何使用这些机制进行线程间的同步控制。此外,还讲解了信号量的概念及其实现方式,包括基于Semaphore的资源访问控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
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文档。
 
附:一个用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();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值