生産者消費者Lock Coditionの実現


ネット上には多くの生産者の消費者モデルがあります。多くはsynchronized、wait、notifyに基づくものです。Lockに基づくものもあります。以下は私がロックを使って、Coditionで実現します。
 
1リポジトリ:
 
class GodOwn {
    //     
    private Lock lock = new ReentrantLock();

    //                
    Condition lessCondition = lock.newCondition();

    //                   
    Condition moreCondition = lock.newCondition();

    private final int max_size = 50;

    private int baseNum = 0;

    int getMax_size() {
        return max_size;
    }

    int getBaseNum() {
        return baseNum;
    }

    void setBaseNum(int baseNum) {
        this.baseNum = baseNum;
    }

    public void produce (int neednum) {
        lock.lock();
        try {
            while (this.getBaseNum() + neednum > this.getMax_size()) {//       
                try {
                    moreCondition.await();//       ,      
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.setBaseNum(this.getBaseNum() + neednum);
            System.out.println("   " + neednum + " ,    " + this.getBaseNum() + " !");
            moreCondition.signalAll();//      ,          ,           
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();//   ,      ,   finally      ,      ,       
        }
    }

    public void reduce(int neednum) {
        lock.lock();
        try {
            while (this.getBaseNum() - neednum < 0) {
                try {
                    lessCondition.await();//             ,      
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.setBaseNum(this.getBaseNum() - neednum);
            System.out.println("   " + neednum + " ,    " + this.getBaseNum() + " !");
            lessCondition.signalAll();//      ,          ,           
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();//   
        }
    }

}
 
 
2生産者モデル
  
class ProduceThread extends Thread {

    private GodOwn godOwn;

    private int neednum;

    ProduceThread(GodOwn godOwn, int neednum) {
        this.godOwn = godOwn;
        this.neednum = neednum;
    }

    public void run() {
        godOwn.produce(neednum);
    }

}
 3消費者モデル
 
 
class ResuseThread extends Thread {
    private GodOwn godOwn;

    private int neednum;

    ResuseThread(GodOwn godOwn, int neednum) {
        this.godOwn = godOwn;
        this.neednum = neednum;
    }

    public void run () {
        this.godOwn.reduce(neednum);
    }
}
 
 
4テストコード
 
    public static void main(String[] args) {
        GodOwn godOwn = new GodOwn();
        ProduceThread p1 = new ProduceThread(godOwn, 50);
        ProduceThread p2 = new ProduceThread(godOwn, 30);
        ProduceThread p3 = new ProduceThread(godOwn, 20);
        ProduceThread p4 = new ProduceThread(godOwn, 20);
        ProduceThread p5 = new ProduceThread(godOwn, 20);
        ResuseThread r1 = new ResuseThread(godOwn, 20);
        ResuseThread r2 = new ResuseThread(godOwn, 20);
        ResuseThread r3 = new ResuseThread(godOwn, 20);
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
        r1.start();
        r2.start();
        r3.start();
    }
 実行結果:
 
   50 ,    50 !
   20 ,    30 !
   20 ,    50 !
   20 ,    30 !
   20 ,    10 !
   20 ,    30 !
   20 ,    50 !
 
以上は簡単な例です。ロックコンディショニングの役割を説明するために!