JAVA技巧(Java线程间的通信)
线程间的通信(生产者-消费者模式)
有以下情况:线程A把橘子放在盘子里(盘子很小,只能装一个橘子)。放橘子后,如果其他线程没有来取橘子,A再放橘子时,盘子里剩下的最后一个橘子会被盖住(事实并非如此),但我们不希望这个好吃的橘子被第二个盖住。我们理想的情况是:线程A把一个橘子放到盘子里后,会立刻通知其他线程去拿。这时线程A会停止往盘子里放橘子,其他线程会立刻通知A橘子被拿走了。这时A会继续放下一个橙子,通知其他线程去拿,以此类推(为了防止生产者永久放上,消费者可以永久拿走,生产者总共可以限制放橙子100次)。
在上面的案例中,线程A和线程B的关系是生产者和消费者。线程A生产橙子,放在盘子里,线程B从盘子里拿橙子,享受美味。而且,为了实现产一取一的一对一过程,线程A必须告诉线程B:橘子已经放好了,来拿吧。你拿着,我再放下一个。当线程B把它拿走的时候,它必须告诉线程A:我拿走了橘子,请赶快放下一个。a和b互相告知的动作就是线程间的通信。
橙子的整个采摘和摆放过程涉及四个对象,分别是生产者(线程A)、消费者(线程B)、消费商品(橙子)和店铺(盘子)。因此,上述过程可以看作是生产者和消费者在商店里交易橙子。下图描绘了上面的整个过程:
下面的代码实现了这种情况:
class mytest 1 {
public static void main(string[]args){
panel pan = new panel();
消费者c =新消费者(潘);
制作人p =新制作人(潘,c);
c . set daemon(true);/*将消费者设置为守护线程,也就是说,当生产者停止生产时,消费者会立即停止消费*/
p . start();
c . start();
}
}
类生成器扩展线程{
Panel pan = null;
消费者c = null
公共生产者(面板pan,消费者c){
this . pan = pan;
this . c = c;
}
public void run(){
synchronized(c){
int count = 0;
//Examda提示:生产者应该总共生产100个橙子
while(count++ < 100){
if(!pan . is blank){
try { c . wait();} catch(Exception ex){ ex . printstacktrace();}
}
int org weight =(int)(math . random()* 100);
Orange org = new Orange(org weight," red ");
pan . putorange(org);
c . notify();
}
}
}
}
}
类消费者扩展线程{
面板pan
公共消费者(Panel pan){
this . pan = pan;
}
public void run(){
synchronized(this){
while(true){
if(pan . is blank){
try { wait();} catch(Exception ex){ ex . printstacktrace();}
}
pan . get orange();
notify();
}
}
}
}
级橙{
int weight;
字符串颜色;
public Orange(int weight,String color){
this . weight = weight;
this . color = color;
}
public String toString(){
return " Orange,weight = " + weight +",color = "+color;
}
}
class Panel {
public boolean is blank = true;
私橙org
public void putOrange(Orange org){
this.org = org;
is blank = false;
system . out . println(" I put:"+org . tostring());
}
public Orange getOrange(){
system . out . println(" I get:"+org . tostring());
is blank = true;
退货组织;
}
}
0条评论