Condition大用途

<p><code>Condition</code> 将 <code>Object</code> 监视器方法(<a target=_blank href=""><code>wait</code></a>、<a target=_blank href=""><code>notify</code></a> 和 <a target=_blank href=""><code>notifyAll</code></a>)分解成截然不同的对象,以便通过将这些对象与任意 <a target=_blank title="java.util.concurrent.locks 中的接口" href=""><code>Lock</code></a> 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,<code>Lock</code> 替代了 <code>synchronized</code> 方法和语句的使用,<code>Condition</code> 替代了 Object 监视器方法的使用。 </p><p>条件(也称为<em>条件队列</em> 或<em>条件变量</em>)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:<em>以原子方式</em> 释放相关的锁,并挂起当前线程,就像 <code>Object.wait</code> 做的那样。 </p><p><code>Condition</code> 实例实质上被绑定到一个锁上。要为特定 <a target=_blank title="java.util.concurrent.locks 中的接口" href=""><code>Lock</code></a> 实例获得 <code>Condition</code> 实例,请使用其 <a target=_blank href=""><code>newCondition()</code></a> 方法。 </p>

public class ConditionThread {
	final ThreeThread tt = new ThreeThread();
	
	public static void main(String[] args) {
		new ConditionThread().init();
	}
	
	public void init(){
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int j = 0; j < 10; j++) {
					try {
						tt.add1();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int j = 0; j < 10; j++) {
					try {
						tt.add2();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		for (int j = 0; j < 10; j++) {
			try {
				tt.add0();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

class ThreeThread{
	Lock lock = new ReentrantLock();
	Condition td0 = lock.newCondition();
	Condition td1 = lock.newCondition();
	Condition td2 = lock.newCondition();
	
	int i = 0;
	int falg = 0;
	public void add0() throws InterruptedException{
		lock.lock();
		try{
			while(falg!=0){
				td0.await();
			}
			i++;
			System.out.println(Thread.currentThread().getName()+":"+i);
			falg = 1;
			td1.signal();
		}finally{
			lock.unlock();
		}
	}
	public void add1() throws InterruptedException{
		lock.lock();
		try{
			while(falg!=1){
				td1.await();
			}
			
			i++;
			System.out.println(Thread.currentThread().getName()+":"+i);
			td2.signal();
			falg = 2;
		}finally{
			lock.unlock();
		}
	}
	public void add2() throws InterruptedException{
		lock.lock();
		try{
			while(falg!=2){
				td2.await();
			}
			i++;
			System.out.println(Thread.currentThread().getName()+":"+i);
			falg = 0;
			td0.signal();
		}finally{
			lock.unlock();
		}
	}
	
}
//在上一篇文章中提到一个缓存区的设计,利用Condition同样可以实现
<pre>class BoundedBuffer {
   <strong>final Lock lock = new ReentrantLock();</strong>
   final Condition notFull  = <strong>lock.newCondition(); </strong>
   final Condition notEmpty = <strong>lock.newCondition(); </strong>

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     <strong>lock.lock();
     try {</strong>
       while (count == items.length) 
         <strong>notFull.await();</strong>
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       <strong>notEmpty.signal();
     } finally {
       lock.unlock();
     }</strong>
   }

   public Object take() throws InterruptedException {
     <strong>lock.lock();
     try {</strong>
       while (count == 0) 
         <strong>notEmpty.await();</strong>
       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       <strong>notFull.signal();</strong>
       return x;
     <strong>} finally {
       lock.unlock();
     }</strong>
   } 
 }


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值