Javaロックベースの生産者消費者モデルの例

3955 ワード

この例では,Javaのロックベースの生産者消費者モデルについて述べる.皆さんの参考にしてください.具体的には以下の通りです.
前の「JavaロックメカニズムLockの使い方」では、ロックメカニズムを簡単に紹介しましたが、ここではlockベースの生産者消費者モデルをさらに分析します.

package com.expgiga.JUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 *         
 */
public class TestProductorAndConsumerForLock {
  public static void main(String[] args) {
    Clerk clerk = new Clerk();
    Productor productor = new Productor(clerk);
    Consumer consumer = new Consumer(clerk);
    new Thread(productor, "   A").start();
    new Thread(consumer, "   B").start();
    new Thread(productor, "   C").start();
    new Thread(consumer, "   D").start();
  }
}
//  
class Clerk {
  private int product = 0;
  private Lock lock = new ReentrantLock();
  private Condition condition = lock.newCondition();
  //    
  public void get() {
    lock.lock();
    try {
      while (product >= 1) { //        ,          
        System.out.println("    !");
        try {
          condition.await();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(Thread.currentThread().getName() + " : " + ++product);
      condition.signalAll();
    } finally {
      lock.unlock();
    }
  }
  //    
  public void sale() {
    lock.lock();
    try {
      while (product <= 0) {
        System.out.println("    !");
        try {
          condition.await();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(Thread.currentThread().getName() + " : " + --product);
      condition.signalAll();
    } finally {
      lock.unlock();
    }
  }
}
//   
class Productor implements Runnable {
  private Clerk clerk;
  public Productor(Clerk clerk) {
    this.clerk = clerk;
  }
  @Override
  public void run() {
    for (int i = 0; i < 20; i++) {
      try {
        Thread.sleep(200);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      clerk.get();
    }
  }
}
//   
class Consumer implements Runnable {
  private Clerk clerk;
  public Consumer(Clerk clerk) {
    this.clerk = clerk;
  }
  @Override
  public void run() {
    for (int i = 0; i < 20; i++) {
      clerk.sale();
    }
  }
}


実行結果:
製品が品切れです.製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1製品がいっぱいです.消費者B:0製品が品切れです!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者C:1製品がいっぱいです.消費者B:0製品が品切れです!製品が品切れです.生産者A:1消費者B:0製品欠品!製品が品切れです.生産者C:1消費者B:0製品欠品!製品が品切れです.生産者A:1消費者B:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0製品欠品!生産者C:1消費者D:0製品欠品!生産者A:1消費者D:0
Javaに関する詳細に興味のある方は、「Javaプロセスとスレッド操作テクニックの概要」、「Javaデータ構造とアルゴリズムチュートリアル」、「Java操作DOMノードテクニックの概要」、「Javaファイルとディレクトリ操作テクニックの概要」、「Javaキャッシュ操作テクニックの概要」を参照してください.
本文で述べたjavaプログラム設計に役立つことを願っています.