ArrayBlockingQueue生産者消費者モデルの実現

6689 ワード

ArrayBlockingQueueは、配列からなる境界ブロックキューであり、一般的な構造方法である.
//fair        , true                
 public ArrayBlockingQueue(int capacity, boolean fair) {
        //         0
        if (capacity <= 0)
            throw new IllegalArgumentException();
        //      
        this.items = new Object[capacity];
        //        
        lock = new ReentrantLock(fair);
        //        
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }
public class ArrayBlockQueueTest {



    /**
     * @param args
     *   ArrayBlockQueue           
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArrayBlockingQueuequeue=new ArrayBlockingQueue<>(100, true);
        ArrayBlockQueueTest test=new ArrayBlockQueueTest();
        test.new Produce(queue).start();
        test.new Consumer(queue).start();

    }

    public class Produce extends Thread{

        /**
         * @param queue
         */
        public Produce(ArrayBlockingQueue queue) {
            super();
            this.queue = queue;
        }

        private ArrayBlockingQueue queue;

        @Override
        public void run(){
            try {
                while (true) {
                    System.out.println("     "+queue.take());
                }

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


    } 



    public class Consumer extends Thread{

        /**
         * @param queue
         */
        public Consumer(ArrayBlockingQueue queue) {
            super();
            this.queue = queue;
        }

        private ArrayBlockingQueue queue;

        @Override
        public void run(){
            int i=0;
            while (i<1000000) {
                System.out.println("    "+i);
                try {
                    queue.put(i++);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }


    } 

}

ここではArrayBlockingQueueのput法とadd法に焦点を当てる.putメソッドはエレメントを格納し,満タンであればスリープスレッド待ちである.addメソッドは最終的にofferメソッドを盗用し,offerメソッドは挿入し,満タンであれば待機しfalseに戻る.一方,addメソッドはofferがfalseを返すとIllegalStateExceptionを誤報する.だから生産消費者モデルではofferやputを使ってaddを使わないでください
   public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

 1. put関数
説明:put関数は要素を格納するために使用され、現在のスレッドが中断されると例外が放出され、キューがいっぱいになるとブロックされて待機します.ここでputはenqueue関数を呼び出し、enqueue関数のソースコードは次のとおりです.
 2. offer関数
説明:offer関数は要素を格納するためにも使用されます.ArrayBlockingQueueのaddメソッドを呼び出すと、offer関数に間接的に呼び出されます.offer関数に要素を追加しても異常は出ません.下位Object配列がいっぱいになるとfalseに戻ります.そうしないと、enqueue関数が呼び出され、下位Object配列に要素が格納されます.notEmpty条件を待つスレッドを起動します.
  3. take関数の説明:take関数は、put関数に対応するArrayBlockingQueueから要素を取得するために使用され、現在のスレッドが中断されると例外が放出され、キューが空の場合、ブロックされて待機します.ここでtakeはdequeue関数を呼び出し、dequeue関数のソースコードは次のとおりです.
説明:dequeue関数は要素を取得するために使用され、notFull条件を待つスレッドが呼び出されます.
  4. poll関数
説明:poll関数はoffer関数に対応する要素を取得するために使用され、例外は放出されません.要素の数が0の場合、nullを返します.そうしないと、dequeue関数を呼び出し、notFull条件を待つスレッドを呼び出します.を返します.
  5. clear関数
説明:clear関数はArrayBlockingQueueを空にし、notFull条件を待つすべてのスレッド(要素を格納するスレッド)を解放します.