Java多线程(6)-生产者与消费者二种实现

一,管程法

使用一个缓冲区,生产者和消费者都是根据缓冲区中的数量来进行活动
在这里插入图片描述
缓冲区的设置有3个好处:

  1. 实现线程的并发协作
    有了缓冲区以后,生产者线程只需要往缓冲区里面放置数据,而不需要管消费者消费的情况;同样,消费者只需要从缓冲区拿数据处理即可,也不需要管生产者生产的情况。
    这样,就从逻辑上实现了“生产者线程”和“消费者线程”的分离。
  2. 解耦了生产者和消费者
    生产者不需要和消费者直接打交道。
  3. 解决忙闲不均,提高效率
    生产者生产数据慢时,缓冲区仍有数据,不影响消费者消费;消费者处理数据慢时,生产者仍然可以继续往缓冲区里面放置数据
public class Thread01 {
 public static void main(String[] agrs) {
  Container container=new Container();
  Productor p=new Productor(container);
  consumer c=new consumer(container);
  p.start();
  c.start();
 }
}
//生产者
class Productor extends Thread{
 Container con;
 public Productor(Container con) {
  this.con=con;
 }
 public void run() {
  //生产
  for(int i=1;i<=100;i++) {
   System.out.println("生产第:"+i+"个馒头");
   con.push(new Steamedbun(i));
  }
 }
}
//消费者
class consumer extends Thread{
 Container con;
 public consumer(Container con) {
  this.con=con;
 }
 public void run() {
  //消费
  for(int i=1;i<=100;i++) {
   {
    System.out.println("消费第:"+con.pop().id+"个馒头");
   }
  }
 }
}
//缓冲区
class Container{
 Steamedbun[] buns=new Steamedbun[10];//存储容器
 int count=0;
 //存储 生产
 public synchronized void push(Steamedbun bun) {
  //存在空间 能生产
  if(count==buns.length) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  buns[count]=bun;
  count++;
  this.notifyAll();
 }
 //取
 public synchronized Steamedbun pop() {
  //何时能消费-->容器中是否有数据
  if(count==0) {
   try {
    this.wait(); //生产者通知消费
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  count--;
  Steamedbun bun=buns[count];
  this.notifyAll(); 
  return bun;
 }
}
class Steamedbun{
 int id;
 public Steamedbun(int id) {
  this.id=id;
 }
}

二、信号灯法

利用标识位,来判断当前状态完成活动,类似于红绿灯

public class Thread02 {
 public static void main(String[] agrs) {
  Tv tv=new Tv();
  new Player(tv).start();
  new Watcher(tv).start();
 }
}
//生产者 演员
class Player extends Thread{
 Tv tv;
 public Player(Tv tv) {
  this.tv=tv;
 }
 public void run() {
  for(int i=0;i<20;i++) {
   if(i%2==0) {
    this.tv.play("奇葩说");
   }else {
    this.tv.play("太污了,喝瓶立白洗洗嘴");
   }
  }
 }
}
//消费者 观众
class Watcher extends Thread{
 Tv tv;
 public Watcher(Tv tv) {
  this.tv=tv;
 }
 public void run() {
  for(int i=0;i<20;i++) {
   tv.watch();
  }
 }
}
//同一个资源 电视
class Tv{
 String voice;
 //如果为真 演员表演 观众等待
 //如果为假 演员等待 观众观看
 boolean flag=true;
 
 //表演
 public synchronized void play(String voice) {
  //演员等待
  if(!flag) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  //表演时刻
  System.out.println("表演了"+voice);
  this.voice=voice;
  this.notifyAll();
  this.flag=!this.flag;
 }
 //观看
 public synchronized void watch() {
  //观众等待
  if(flag) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  System.out.println("听到"+voice);
  this.notifyAll();
  this.flag=!this.flag;
 }
}
发布了45 篇原创文章 · 获赞 43 · 访问量 7067

猜你喜欢

转载自blog.csdn.net/qq_42193790/article/details/104441226
今日推荐