javaマルチスレッド総括六:経典生産者消費者問題実現


これはスレッド同期の古典的な例であり、ソースコードは以下の通りである。
package demo.thread;

/**
 *           :              ,           。
 *                。      ,       ,         
 */

public class ProducersAndConsumers {
	public static void main(String[] args) {
		Storage storage = new Storage();
		Thread consumer = new Thread(new Consumer(storage));
		consumer.setName("   ");
		Thread producer = new Thread(new Producer(storage));
		producer.setName("   ");
		consumer.start();
		producer.start();
	}
}

/**
 *    
 */
class Consumer implements Runnable {
	private Storage storage;

	public Consumer(Storage storage) {
		this.storage = storage;
	}

	@Override
	public void run() {
		storage.pop();
	}
}

/**
 *    
 */
class Producer implements Runnable {
	private Storage storage;

	public Producer(Storage storage) {
		this.storage = storage;
	}

	@Override
	public void run() {
		Product product = new Product("090505105", "  ");
		storage.push(product);
	}

}

/**
 *    
 */
class Product {
	private String id;//   id
	private String name;//     

	public Product(String id, String name) {
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "(  ID:" + id + "     :" + name + ")";
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

/**
 *  
 */
class Storage {
	//      10
	private Product[] products = new Product[10];
	private int top = 0;

	//            
	public synchronized void push(Product product) {
		while (top == products.length) {
			try {
				wait();//    ,  
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
        //       
		products[top++] = product;
		System.out.println(Thread.currentThread().getName() + "      "
				+ product);
		notifyAll();//      

	}

	//            
	public synchronized Product pop() {
		while (top == 0) {
			try {
				wait();//   ,  
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		//       
		--top;
		Product p = new Product(products[top].getId(), products[top].getName());
		products[top] = null;
		System.out.println(Thread.currentThread().getName() + "      " + p);
		notifyAll();//      
		return p;
	}
}
 
実行結果:
生産者が生産した製品(製品ID:09.0535製品名:電話)消費者が消費した製品(製品ID:09.059105製品名:電話)