简单又经典的生产者消费者线程模式

 

 

/**

建立桌子,并启动代表厨师、客人的线程。传进MakerThread与EaterThread构造器的随机数种子

*/

public class Main{

 

public static void main(String[] args){

Table table=new Table(3);

new MakerThread("MakerThread-1",table,31415).start();

new MakerThread("MakerThread-2",table,92653).start();

new MakerThread("MakerThread-3",table,58979).start();

new EaterThread("EaterThread-1",table,32384).start();

new EaterThread("EaterThread-1",table,62643).start();

new EaterThread("EaterThread-1",table,38327).start();

}

}

 

 

 

/**

厨师,制作蛋糕的类

*/

 

import java.util.Random;

public class MakerThread extends Thread{

 

private final Random random;

private final Table table;

private static int id=0;//蛋糕流水号(所有厨师相同)

public MakerThread(String name,Table table,long seed){

super(name);

this.table=table;

this.random=new Random(seed);

}

public void run(){

try{

while(true){

Thread.sleep(random.nextInt(1000));

String cake="[Cake No."+nextId()+" by "+getName()+"";

table.put(cake);

}

}catch(InterruptedException e){

e.printStackTrace();

}

}

private static synchronized int nextId(){

return id++;

}

}



/**
客人,吃蛋糕的类
*/

import java.util.Random;

public class EaterThread extends Thread{
private final Random random;
private final Table table;
public EaterThread(String name,Table table,long seed){
super(name);
this.table=table;
this.random=new Random(seed);
}

 
public void run(){
try{
while(true){
String cake=table.take();
Thread.sleep(random.nextInt(1000));
}
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}

/**
放蛋糕的桌子
**/

public class Table{

private final String[] buffer;
private int tail;//下一个put的地方
private int head;//下一个take的地方
private int count;//buffer内的蛋糕数
public Table(int count){
this.buffer=new String[count];
this.head=0;
this.tail=0;
this.count=0;
}
//放置蛋糕
public synchronized void put(String cake) throws InterruptedException{
System.out.println(Thread.currentThread().getName()+" puts "+cake);
while(count>=buffer.length){
wait();
}
buffer[tail]=cake;
tail=(tail+1)%buffer.length;
count++;
notifyAll();
}
//获取蛋糕
public synchronized String take() throws InterruptedException{
while(count<=0){
wait();
}
String cake=buffer[head];
head=(head+1)%buffer.length;
count--;
notifyAll();
System.out.println(Thread.currentThread().getName()+" take "+cake );
return cake;
}
}




这个Pattern中,有着建立Data参与者的线程(Producter参与者)与使用Data参与者得线程(Consumer参与者)在运行。两者之间安插了Channel参与者(Table)。并委托channel参与者来保管想要传递的Data参与者。Channel参与者的工作可说是Data参与者得中继站、桥梁及沟通管道。因为可能会有多个线程使用到Channel参与者,所以Channel参与者中必须进行共享互斥。这样的设计使线程之间可以安全的沟通。若Channel参与者可囤积Data参与者得空间足够,可作为Producer参与者与Consumer参与者处理速度的缓冲。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值