再美不及姑娘你
又见西风上碧树
posts - 135,comments - 7,views - 48056

需求:某小区单元定制牛奶,送奶人员会将牛奶放入奶箱,该奶箱共能存放30瓶牛奶,居民从奶箱中取奶。请用程序实现这一过程

分析:

1.创建奶箱类:定义一个成员变量,表示是奶箱中的第几瓶奶,提供存放牛奶和取出牛奶的方法

2.创建生产厂家类:实现Runable接口,重写run方法,调用存放牛奶的方法

3.创建居民类:实现Runable接口,重写run方法,调用取出牛奶的方法

4.创建测试类:

1.创建奶箱对象

2.创建生产厂家对象,并将奶箱对象作为构造方法参数传递,调用存储牛奶的方法

3.创建居民对象,并将奶箱对象作为构造方法参数传递,调用取出牛奶的方法

4.创建两个线程,分别把生产厂家对象、居民对象作为构造方法参数传递

5.启动线程

奶箱类

package Demo041902;
public class Box {
  //定义一个成员变量,表示是奶箱中的第几瓶奶,提供存放牛奶和取出牛奶的方法
  private int milk;
  //创建奶箱状态,判断是否为空
  Boolean state=false;
  //存放牛奶
  public synchronized void put(int milk){
      //先判断奶箱是否为空,是:放奶入箱;否:休眠
      if (state){
          try {
              wait();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
      //state=false,放奶入箱
      this.milk=milk;
      System.out.println("生产厂家将第"+this.milk+"瓶奶放入奶箱");
      //修改状态
      state=true;
      //唤醒线程
      notifyAll();
  }
  public synchronized void get(){
      //判断奶箱是否为空,空的就休眠
      if (!state){
          try {
              wait();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
      //奶箱不空,就取奶
      System.out.println("居民取出第"+this.milk+"瓶奶");
      //取完后修改状态
      state=false;
      //唤醒线程
      notifyAll();
  }

}

生产厂家类

package Demo041902;
public class producter implements Runnable {
  private Box b;
  public producter(Box b) {
      this.b=b;
  }
  //实现Runable接口,重写run方法,调用存放牛奶的方法
  @Override
  public void run() {
      for (int i=1;i<=5;i++){
          b.put(i);
      }
  }
}

消费者类

package Demo041902;
public class consumer implements Runnable{
  private Box b;
  public consumer(Box b) {
      this.b=b;
  }
  //实现Runable接口,重写run方法,调用取出牛奶的方法
  @Override
  public void run() {
      while(true){
          b.get();
      }
  }
}

测试类

package Demo041902;
public class Demo {
  public static void main(String[] args) {
      //创建奶箱对象
      Box b=new Box();
      //创建生产厂家对象,并将奶箱对象作为构造方法参数传递,调用存储牛奶的方法
      producter p=new producter(b);
      //创建居民对象,并将奶箱对象作为构造方法参数传递,调用取出牛奶的方法
      consumer c=new consumer(b);
      //创建两个线程,分别把生产厂家对象、居民对象作为构造方法参数传递
      Thread t=new Thread(p,"生产者");
      Thread t1=new Thread(c,"消费者");
      t.start();
      t1.start();
  }
}

容易出现的问题:

1.不判断奶箱的状态,会出现一直取最后一瓶奶

2.IllegalMonitorStateException:抛出以表示线程已尝试在对象的监视器上等待或通知其他线程等待对象的监视器,而不拥有指定的监视器。线程没有同步会抛出这个异常,需要在方法上加同步锁

3.去除第一瓶奶后不往下走,线程休眠后没有唤醒

posted on   再美不及姑娘你  阅读(158)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示