java condition条件队列 生产者消费模式

/**
 * Date:2016年9月7日下午7:56:03
 * Copyright (c) 2016, www.bwbroad.com All Rights Reserved.
 *
 */

package test.condition;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Description: TODO <br/>
 * Date: 2016年9月7日 下午7:56:03 <br/>
 * 
 * @author xuejianxin
 */
public class ConditionTest1 {

	public static int CHUSHI = 6;
	public static int CHIHUO = 10;

	public static void main(String[] args) throws Exception {

		/**
		 这就是多个Condition的强大之处,假设缓存队列中已经存满,那么阻塞的肯定是写线程,
		 唤醒的肯定是读线程,相反,阻塞的肯定是读线程,唤醒的肯定是写线程,那么假设只有一个Condition会有什么效果呢,
		 缓存队列中已经存满,这个Lock不知道唤醒的是读线程还是写线程了,如果唤醒的是读线程,
		 皆大欢喜,如果唤醒的是写线程,那么线程刚被唤醒,又被阻塞了,这时又去唤醒,这样就浪费了很多时间。
		 */
		
		
		
		System.out.println(new Random().nextInt(10));

		Panzi panzi = new Panzi(2);

		Chushi chushi = new Chushi("厨师", panzi);
		chushi.start();
		// Chushi chushi1 = new Chushi("厨师1", panzi);
		// chushi1.start();

		Chihuo chihuo1 = new Chihuo("吃货1", panzi);
		Chihuo chihuo2 = new Chihuo("吃货2", panzi);
		chihuo1.start();
		chihuo2.start();

	}

	public static class Panzi {
		private int count = 0;
		private Queue<String> foods;

		private Lock lock = new ReentrantLock();
		private Condition chushiCon = lock.newCondition();//厨师等待的条件
		private Condition chihuoCon = lock.newCondition();//吃货等待的条件

		public Panzi(int count) {
			this.count = count;
			foods = new LinkedList<String>();
		}

		public/* synchronized */void put(String name, String food) {
			lock.lock();
			try {
				while (foods.size() >= count) {// 这里必须用循环
					System.out.printf(
							"%d/%d,%s 快吃啊...........................\r\n",
							foods.size(), this.count, name);
					try {
						// this.wait();
						chushiCon.await();// 厨师等待
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				foods.offer(food);
				System.out.printf("%d/%d,%s----->%s\r\n", foods.size(),
						this.count, name, food);
				// this.notifyAll();
				chihuoCon.signalAll();// 唤醒吃货
			} finally {
				lock.unlock();//一定要在 finally 里释放锁
			}
		}

		public/* synchronized */String get(String name) {
			lock.lock();
			try {
				while (foods.size() == 0) {// 这里必须用循环
					System.out.printf("%d/%d,%s 我等待花儿都谢了...\r\n", foods.size(),
							this.count, name);
					try {
						// this.wait();
						chihuoCon.await();// 吃货等待
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				String food = foods.poll();
				System.out.printf("%d/%d,%s******>%s\r\n", foods.size(),
						this.count, name, food);
				// this.notifyAll();
				chushiCon.signalAll();//唤醒厨师
				return food;
			} finally {
				lock.unlock();
			}
		}

	}

	// 厨师类
	public static class Chushi extends Thread {
		private Panzi panzi;
		private String name;

		public Chushi(String name, Panzi panzi) {
			this.name = name;
			this.panzi = panzi;
		}

		@Override
		public void run() {
			int i = 1;
			String s;
			while (true) {
				s = "food" + (i++);
				panzi.put(this.name, s);
				i++;
				try {
					Thread.sleep(new Random().nextInt(CHUSHI) * 100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}

	// 吃货类
	public static class Chihuo extends Thread {
		private String name;
		private Panzi panzi;

		public Chihuo(String name, Panzi panzi) {
			this.name = name;
			this.panzi = panzi;
		}

		@Override
		public void run() {
			while (true) {
				panzi.get(this.name);
				try {
					Thread.sleep(new Random().nextInt(CHIHUO) * 100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值