本帖最后由 小歪 于 2014-3-16 21:10 编辑
生产者与消费者(线程同步与死锁、等待与唤醒)
设计一个生产电脑和搬运电脑类,要求生产出一台电脑搬走一台电脑,如果没有新的电脑
生产出来,则搬运工要等待新电脑产出;如果生产出的电脑没有搬走,则要等待电脑搬走之后
再生产,并统计出生产的电脑数量。
*/
class Computer{ //定义所要生产的产品类
private String name="厂家"; //用户类型,生产时是厂家,搬运时是搬运工
private String computer="生产一台电脑"; //起初默认厂家生产一台电脑
private boolean flag=false; //设置标志位,用于判断上一步是‘生产’还是‘搬运’
public void setComputer(String computer) //设置属性
{
this.computer=computer;
}
public String getComputer() //得到属性
{
return computer;
}
public void setname(String name) //设置属性
{
this.name=name;
}
public String getname() //得到属性
{
return name;
}
public synchronized void set(String name,String computer) //加入同步方法,设置信息,试生产者与消费者各自的信息同步
{
if(!flag) //如果标志为假,表示不可以生产
{
try{
super.wait(); //等待搬运工取走
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.setname(name);
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
this.setComputer(computer);
flag=false; //已生产完,改变标志位
super.notify(); //唤醒其他等待中线程,准备取走
}
public synchronized void get() //加入同步方法,获取生产者或消费者的信息
{
if(flag) //如果标志为真,表示不可以搬运
{
try{
super.wait(); //等待生产者生产完
}catch(InterruptedException e){
e.printStackTrace();
}
}
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getname()+"---->"+this.getComputer()); //取走
flag=true; //已取走,改变标志位
super.notify(); //唤醒其他等待中线程,准备生产
}
}
class Producer implements Runnable{ //定义生产者
private Computer computer=null;
public Producer(Computer computer) //通过构造函数为computer属性 初始化
{
this.computer=computer;
}
public void run()
{
boolean flag=false; //如果标志位是true状态就生产状态,false就搬运状态
for(int i=0;i<50;i++) //假设进行50次动作
{
if(flag)
{
this.computer.set("厂家","生产一台电脑");
flag=false;
}else{
this.computer.set("搬运工","取走一台电脑");
flag=true;
}
}
}
}
class Consumer implements Runnable{ //定义消费者
private Computer computer=null;
public Consumer(Computer computer)
{
this.computer=computer;
}
public void run()
{
for(int i=0;i<50;i++) //假设进行50次动作
{
try{ //模拟网络延时
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
this.computer.get(); //取出当前状态
}
}
}
public class ComputerDeal{
public static void main(String args[])
{
Computer com=new Computer();
Producer pro=new Producer(com);
Consumer con=new Consumer(com);
new Thread(pro).start();
new Thread(con).start();
}
}
运行结果:
总结
1、在本程序操作中需要以下两个问题:
生产者要不断生产,但是不能生产错误信息或重复生产。
消费者要i不断取走,但不能重复取走。
2、Object类中对线程的支持
等待:wait()方法
唤醒:notify()、notifyAll()的区别
3、此程序只是举例对于同步,等待、唤醒机制的操作,程序的实际含义不必追究。
|