条件队列


wait()、notify()和notifyAll()一般是跟synchronized配合一起使用,这些方法都是Object类提供的。
当线程重wait()状态下被唤醒,wait()在被唤醒后还需要重新去获取锁,此时它重新请求锁时并没有具备任何特殊的优先级,
要与任何其他尝试进入同步代码块的线程一起去竞争获取锁,如果获取锁失败的话,会继续停留在当前的wait()方法状态下。
所以wait方法继续执行时,一般会先通过一个条件判断,所以一般是在一个循环中去调用wait()方法。

由于多个线程可以基于不同的条件在同一个条件队列中等待,所以一般是要用notifyAll(),避免造成消息的丢失。
因为调用notify()只会唤醒一个线程,但是这个线程可能并不能从满足条件,这个时候系统其它线程满足条件会一直等待并无法被唤醒,这是一个非常危险的操作。所以一定要使用notifyAll()。

那么什么情况下使用notify()呢?

(1)所有线程的wait()前置判断条件只有一个并且都是一样的
(2)单进单出,每次通知发出后,这个条件下最多只有一个线程可以去执行。


Condition类的await()、signal()和signalAll(),一般是配合Lock一起使用,是显式的线程间协调同步操作类。
每个Lock中可以有多个Condition,如notEmpty、notFull等。
这些方法都是在某个具体的Condition条件队列中调用,唤醒的时候也是类似,使用对应的Condition来唤醒一个或者多个等待的线程。
和wait()、notify()类似,使用这些方法时也需要先通过Lock获取锁,await()方法同样会释放锁,并挂起当前线程,等待被通知唤醒去重新竞争锁。

 

 

package conditionDemo;

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



public class ConditionBoundedBuffer<T> {
	private final T[] array;
	 
	private int head;
 
	private int tail;
 
	private int count;
 
	private java.util.concurrent.locks.Lock lock = new ReentrantLock();
 
	private Condition isFull = lock.newCondition();
 
	private Condition isEmpty = lock.newCondition();
 
	public ConditionBoundedBuffer(int size) {
		array = (T[]) new Object[size];
	}
 
	public void put(T item) throws InterruptedException {
		lock.lock();
		try {
			while (count == array.length) {
				isFull.await();
			}
 
			array[tail] = item;
			if (++tail == array.length) {
				tail = 0;
			}
			count++;
			System.out.println("Add item: " + item);
			// 通知isEmpty条件队列有元素进入
			isEmpty.signal();
		} finally {
			lock.unlock();
		}
	}
 
	public T take() throws InterruptedException {
		lock.lock();
		try {
			while (count == 0) {
				isEmpty.await();
			}
 
			T item = array[head];
			if (++head == array.length) {
				head = 0;
			}
			count--;
			System.out.println("Take item: " + item);
			// 通知isFull条件队列有元素出去
			isFull.signal();
			return item;
		} finally {
			lock.unlock();
		}
	}

}
package conditionDemo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class testMain {
	public static void main(String[] args){
		final ConditionBoundedBuffer<Integer> buff=new ConditionBoundedBuffer<Integer>(10);
		ExecutorService pool=Executors.newCachedThreadPool();
		final AtomicInteger atomicInteger=new AtomicInteger(0);
		for(int i=0;i<10;i++){
			pool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						buff.take();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
			});
			pool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						buff.put(atomicInteger.incrementAndGet());
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
			
		}
		 
		pool.shutdown();
	}
}

当每个锁上有多个等待条件时,可以优先使用Condition,这样可以具体一个Condition控制一个条件等待

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值