/**
* 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
* Date: 2016年9月7日 下午7:56:03
*
* @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 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();
}
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();
}
}
}
}
}