写在开头:这个不是原创的,代码不知道在哪儿看到的(如果侵权,请联系我)。
新手,大家一起学习吧。
这里用盘子和鸡蛋。盘子作为临界资源。
1,作为生产者:如果盘子是空的,则获取盘子,放置鸡蛋,然后释放盘子;否则等待。
2,作为消费者:如果盘子有鸡蛋,则获取盘子,拿取鸡蛋,然后释放盘子;否则等待。
先来一个盘子。一个list放鸡蛋,有拿鸡蛋和放鸡蛋方法。
/**
* 生产者-消费者模型
* 互斥模型
*/
package org.michael.plate;
import java.util.ArrayList;
import java.util.List;
public class Plate {
List<Object> eggs = new ArrayList<Object>();
/**
* 拿鸡蛋
* @return 鸡蛋
*/
public synchronized Object getEgg(){
while(eggs.size() == 0){
try{
this.wait();
}catch(InterruptedException e){
}
}
Object egg = eggs.get(0);//拿鸡蛋
eggs.clear();//清空盘子
notify();//唤醒阻塞队列的某线程到就绪队列
System.out.println("i get an egg!");
return egg;
}
/**
* 放鸡蛋
* @param egg 鸡蛋
*/
public synchronized void putEgg(Object egg){
while(eggs.size() > 0){
try{
this.wait();
}catch(InterruptedException e){
}
}
eggs.add(egg);//放入鸡蛋
notify();//唤醒阻塞队列的某线程到就绪队列
System.out.println("i put an egg!");
}
}
再来一个生产者(放鸡蛋):
package org.michael.plate;
/**
* 放鸡蛋线程
* @author Michael
*
*/
public class PutEggThread extends Thread{
private Plate plate;
private Object egg=new Object();
public PutEggThread(Plate plate){
this.plate = plate;
}
public void run(){
for(int i=0; i<5; i++){
plate.putEgg(egg);
}
}
}
消费者(拿鸡蛋):
package org.michael.plate;
/**
* 拿鸡蛋线程
* @author Michael
*
*/
public class GetEggThread extends Thread{
private Plate plate;
public GetEggThread(Plate plate){
this.plate = plate;
}
public void run(){
for(int i=0;i<5;i++){
plate.getEgg();
}
}
}
主函数:
package org.michael.plate;
/*
* 生产者-消费者模型测试类
*/
public class mainFunc {
public static void main(String[] args) {
System.out.println("生产者-消费者测试开始:");
Plate plate = new Plate();
Thread putEggs = new PutEggThread(plate);
Thread getEggs = new GetEggThread(plate);
putEggs.start();
getEggs.start();
try {
// 等子线程执行完
putEggs.join();
getEggs.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产者-消费者测试完成。");
}
}
输出结果:
生产者-消费者测试开始:
i put an egg!
i get an egg!
i put an egg!
i get an egg!
i put an egg!
i get an egg!
i put an egg!
i get an egg!
i put an egg!
i get an egg!
生产者-消费者测试完成。