一、生产者消费者问题
做为苦逼的程序员的我们基本没有不知道生产者消费者问题的,这个经典的问题充分体现了进程同步的问题,还是简单的说下它的概念,生产者和消费者是两个线程,生产者线程生产物品放到空的缓冲区内(可能是一个list),消费者线程从缓冲区内取出物品进行消费并释放缓冲区,缓冲区有个固定大小,当生产者线程将缓冲区填充满时,生产者线程处于等待状态,等待消费者线程消费;当缓冲区消费空了后,消费者线程处于等待状态,等待生产者线程进行生产。当然生产者和消费者也可以有多个线程充当,但是操作的进程地址空间却只能是同一个。
这个经典的问题体现了多线程编程的一些要注意的地方,比如对同一资源进行访问所产生的互斥和同步问题。
下面看下对生产者消费者问题的实现。
物品类:
Java代码
packagecom.lifanghu.procon;
/**
* 食物
* @author lifh
* @mail wslfh2005@163.com
* @since 2012-6-22 上午08:13:34
* @name com.lifanghu.procon.Food.java
* @version 1.0
*/
publicclassFood {
privateString name;
publicString getName() {
returnname;
}
publicvoidsetName(String name) {
this.name = name;
}
}
缓冲区:
Java代码
packagecom.lifanghu.procon;
importjava.util.ArrayList;
importjava.util.List;
/**
* 容器,缓冲区
* @author lifh
* @mail wslfh2005@163.com
* @since 2012-6-22 上午08:33:56
* @name com.lifanghu.procon.Container.java
* @version 1.0
*/
publicclassContainer {
//缓冲区大小
privateintsize;
privateListfoods;
publicContainer(intsize) {
this.size = size;
foods =newArrayList(size);
}
publicsynchronizedvoidpoll(Food food) {
while(foods.size() >= size) {
try{
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
foods.add(food);
notifyAll();
}
publicsynchronizedFood offer() {
Food food =null;
while(foods.size() ==0) {
try{
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
food = foods.remove(foods.size() -1);
notifyAll();
returnfood;
}
}
生产者:
Java代码
packagecom.lifanghu.procon;
/**
* 生产者
* @author lifh
* @mail wslfh2005@163.com
* @since 2012-6-22 上午08:13:26
* @name com.lifanghu.procon.Producer.java
* @version 1.0
*/
publicclassProducerimplementsRunnable {
privateContainer container;
publicProducer(Container container) {
super();
this.container = container;
}
publicvoidrun() {
for(inti =0; i <10; i++) {
Food food =newFood();
food.setName("馒头"+ i);
System.out.println("生产者生产出"+ food.getName());
container.poll(food);
try{
Thread.sleep((long) (Math.random() *3000));
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者: