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容器造成信號丟失,並不一定能通知到我們想要告知的線程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM