wait/notify

某面试题,实现一个生产者——消费者模型

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

public class Test {

    public Queue<Integer> gun = new LinkedList<Integer>(); //
    public final int maxCount = 20; // 枪里面最多上20发子弹

    public final int maxbulletCount = 200; // 枪里面最多上20发子弹
    public final int[] bullets = new int[maxbulletCount];
    private int pos = 0;

    public Test() {
        Random r = new Random();
        for (int i = 0; i < maxbulletCount; i++) {
            bullets[i] = r.nextInt(1000);
        }
    }

    private int getBullet() {
        return pos < maxbulletCount ? bullets[pos++] : -1;
    }

    class Producer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (gun) {
                    try {
                        if(gun.size() == maxCount){
                            System.out.println("*********** 枪膛已经上满子弹");
                            gun.wait();
                        } else {
                            int i = getBullet();
                            if (i == -1) {
                                System.out.println("*********** 子弹已经用完");
                                Thread.interrupted();
                            } else {
                                gun.add(i);
                                System.out.println("*********** 子弹" + i + "上膛 枪里面还有" + gun.size() + "颗子弹");
                                
                                try {
                                    Thread.sleep(199);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                        
                        gun.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        
    }

    class Consumer implements Runnable {
        public void run() {
            while (true) {
                synchronized (gun) {
                    try {
                        if( gun.size() == 0 ){
                            System.out.println("*********** 枪没子弹了 ");
                            gun.wait();
                        } else {
                            Integer bullet = gun.poll();
                            System.out.println("*********** 使用子弹" + bullet + ", 枪里面还有" + gun.size() + "颗子弹");
                            
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        
                        gun.notifyAll();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
    }

    public static void main(String[] args) {
        Test t = new Test();
        Thread p = new Thread(t.new Producer());
        Thread c = new Thread(t.new Consumer());
        p.start();
        c.start();
    }
}

值得注意的是:notify并不释放锁,只是唤醒其他线程来竞争锁,当synchronized代码执行完才释放锁。一般建议使用notifyAll,不使用notify,因为notify容器造成信号丢失,并不一定能通知到我们想要告知的线程。

原文地址:https://www.cnblogs.com/greys/p/10735899.html