java并发 locks包:Condition(二)

本文基本是JDK文档中的说明内容,但是已经很好的解释了Condition对象的使用方法。

 

Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。 

 

条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。 

 

Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。 

 

作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法。如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。 

 

代码实例:

package com.mutex;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 实现自己的阻塞队列
 */
public class MyBlockingQueue<T> {

	private final Lock lock = new ReentrantLock();

	private Condition notFull = lock.newCondition();
	private Condition notEmpty = lock.newCondition();

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

	public void put(T x) {
		lock.lock();
		try {
			while (count == items.length)
				notFull.await();

			items[putptr] = x;
			if (++putptr == items.length)
				putptr = 0;

			++count;

			notEmpty.signal();

		} catch (InterruptedException e) {
			// todo
		} finally {
			lock.unlock();
		}
	}

	public T take() {
		lock.lock();
		try {
			while (count == 0)
				notEmpty.await();

			T x = (T) items[takeptr];
			if (++takeptr == items.length)
				takeptr = 0;

			--count;

			notFull.signal();

			return x;
		} catch (InterruptedException e) {
			// todo
			return null;
		} finally {
			lock.unlock();
		}

	}

	public static void main(String[] args) {

		final MyBlockingQueue<String> bq = new MyBlockingQueue<String>();

		new Thread() {
			public void run() {
				int count = 0;
				while (true) {
					++count;
					bq.put("test: " + count);
				}
			}
		}.start();

		new Thread() {
			public void run() {
				while (true) {
					System.out.println(bq.take());
				}
			}
		}.start();
	}

}

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值