2

生产者消费者模型

题目

采用多线程技术,例如wait/notify,设计实现一个符合生产者和消费者问题的程序,对某一个对象(枪膛)进行操作,其最大容量是20颗子弹,生产者线程是一个压入线程,它不断向枪膛中压入子弹,消费者线程是一个射出线程,它不断从枪膛中射出子弹。

请实现上面的程序

import java.util.ArrayList;
import java.util.List;

public class GunTest{

    private static final Object o = new Object();
    static List<String> listBullet = new ArrayList<>();
    static volatile int Capacity = 0;

    static class GunLoad extends Thread {

        @Override
        public void run() {
            while (true) {
                synchronized (o) {
                    while (Capacity >= 20) {
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    listBullet.add("bullet");
                    ++Capacity;
                    System.out.println(Thread.currentThread().getName()
                            + " load a bullet totalnum[" + Capacity +"]");
                    o.notifyAll();
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class GunFire extends Thread {
        @Override
        public void run() {
            while (true) {
                synchronized (o) {
                    while (Capacity <= 0) {
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName()
                            + " fire a " + listBullet.get(0) + "totalnum[" + Capacity +"]");
                    listBullet.remove(0);
                    --Capacity;
                    o.notifyAll();
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        //可以通过调节加载弹夹和发射子弹的线程数,得到不一样的结果
        for (int i = 0; i < 10; ++i){
            new GunFire().start();
        }

        for (int j = 0; j < 1; ++j){
            new GunLoad().start();
        }

    }
}

运行结果:

Thread-1 fire a bullettotalnum[1]
Thread-10 load a bullet totalnum[1]
Thread-5 fire a bullettotalnum[1]
Thread-10 load a bullet totalnum[1]
Thread-1 fire a bullettotalnum[1]
Thread-10 load a bullet totalnum[1]
Thread-5 fire a bullettotalnum[1]
Thread-10 load a bullet totalnum[1]
Thread-5 fire a bullettotalnum[1]

加载子弹线程较少,发射子弹线程较多,所以刚加载的子弹就会被发射,弹夹中总是只有一颗子弹
通过调节线程数可以获得不一样的结果


DragonflyDavid
182 声望19 粉丝

尽心,知命