【多线程模拟包子喂狗,其中一个包子铺线程发包子,每次只发一个,2个狗线程抢包子,三个线程用同一把锁,代码如下】
===========测试类====================public class Demo {
 public static void main(String[] args) {
 ArrayList<String> baozi = new ArrayList<>();//存"包子"
 BaoZiPu bzp = new BaoZiPu(baozi, "包子铺");
 Dog_1 dg1 = new Dog_1(baozi, "1");
 Dog_2 dg2 = new Dog_2(baozi, "2");
//创建3个线程
 bzp.start();
 dg1.start();
 dg2.start();
 }
}
===========包子铺类========================public class BaoZiPu extends Thread {
 ArrayList<String> baozi;
 public BaoZiPu(ArrayList<String> baozi, String name) {
 super(name);
 this.baozi = baozi;
 }//给线程命名,共用同地址值baozi
 @Override
 public void run() {
 while (true) {
 synchronized (baozi) {    //三个线程用同一个锁
 if (baozi.size() > 0) {
 try {
 baozi.wait();//如果有包子等待dg1吃掉后唤醒
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 try {
 Thread.sleep(10);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 baozi.add("baozi");
 System.out.println("做包子");
 baozi.notify();
 }
 }
 }
}
===========第一条狗========================public class Dog_1 extends Thread {
 ArrayList<String> baozi;
 public Dog_1(ArrayList<String> baozi, String name) {
 super(name);
 this.baozi = baozi;
 }//给线程命名,共用同地址值baozi
 @Override
 public void run() {
 while (true) {
 synchronized (baozi) {//三个线程用同一个锁
 if (baozi.size() == 0) {//如果没包子等待bzp生成后唤醒。
 try {
 baozi.wait();
 } catch (InterruptedException e) {
 System.out.println("????");
 e.printStackTrace();
 }
 }
 System.out.println(Thread.currentThread().getName() + "正在吃包子");
 baozi.remove(0);
 baozi.notify();
 }
 }
 }
}
===========第二条狗========================public class Dog_2 extends Thread {
 ArrayList<String> baozi;
 public Dog_2(ArrayList<String> baozi, String name) {
 super(name);
 this.baozi = baozi;
 }//给线程命名,共用同地址值baozi
 public void run() {
 while (true) {
 synchronized (baozi) {//三个线程用同一个锁
 if (baozi.size() == 0) {//如果没包子等待bzp生成后唤醒。
 try {
 baozi.wait();
 } catch (InterruptedException e) {
 System.out.println("????");
 e.printStackTrace();
 }
 }
 System.out.println(Thread.currentThread().getName() + "正在吃包子");
 baozi.remove(0);
 baozi.notify();
 }
 }
 }
}【图片】===============================================
运行后会出现越界异常 ,求大神支招。感谢!!!

解决方案 »

  1.   

    package threaddemo;public class ThreadDemo06 {
    // 【多线程模拟包子喂狗,其中一个包子铺线程发包子,每次只发一个,2个狗线程抢包子,三个线程用同一把锁,代码如下】 public static void main(String[] args) {
    Thread01 thread01 = new Thread01();//包子铺线程
    Thread02 thread02 = new Thread02(thread01);//狗1
    Thread03 thread03 = new Thread03(thread01);//狗2
    thread01.start();
    thread02.start();
    thread03.start();
    }
    }class Thread01 extends Thread {
    public static int num; public Thread01() {
    // TODO Auto-generated constructor stub
    } public Thread01(int num) {
    // TODO Auto-generated constructor stub
    this.num = num;
    } @Override
    public void run() {
    // TODO Auto-generated method stub
    while (true) {
    synchronized (Lock.LockA) {//这个是自定义锁对象
    if (num == 0) {
    System.out.println("正在生产包子");
    num++;
    }
    Lock.LockA.notifyAll();//唤醒其他锁对象
    try {
    Lock.LockA.wait();//使当前线程进入等待队列
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }}class Thread02 extends Thread {
    Thread01 thread01; public Thread02(Thread01 thread01) { this.thread01 = thread01;
    } @Override
    public void run() {
    // TODO Auto-generated method stub
    while (true) { synchronized (Lock.LockA) {
    if (thread01.num > 0) {
    System.out.println(Thread.currentThread().getName() + "正在吃包子");
    thread01.num--;//吃一次包子,包子数量减-
    Lock.LockA.notifyAll();
    try {
    Lock.LockA.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    }
    }class Thread03 extends Thread {
    Thread01 thread01; public Thread03(Thread01 thread01) {
    this.thread01 = thread01;
    } @Override
    public void run() {
    // TODO Auto-generated method stub
    while (true) {
    synchronized (Lock.LockA) {
    if (thread01.num > 0) {
    System.out.println(Thread.currentThread().getName() + "正在吃包子");
    thread01.num--;
    Lock.LockA.notifyAll();
    try {
    Lock.LockA.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } }
    }
    }
    }