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

来源:互联网 发布:java微信自定义菜单 编辑:程序博客网 时间:2024/04/28 11:40
/** * 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;}@Overridepublic 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;}@Overridepublic void run() {while (true) {panzi.get(this.name);try {Thread.sleep(new Random().nextInt(CHIHUO) * 100);} catch (InterruptedException e) {e.printStackTrace();}}}}}

0 0
原创粉丝点击