`
woxiaoe
  • 浏览: 276724 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java线程学习笔记(九)生产者消费者问题

    博客分类:
  • Java
阅读更多

用多线程来模拟生产者消费者问题。用到BlockingQueue来实现更方便和安全。

 

模拟一个厨师生成产品,消费者消费,当产品数大于10的时候厨师休息,但产品数不够时厨师接着工作。

 

 

package com.woxiaoe.study.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 生产者 消费者 模拟
 * @author 小e
 *
 * 2010-4-29 下午09:32:43
 */

class Cook implements Runnable{
	private int productId;
	private BlockingQueue<Product> products;
	private boolean rest;
	public Cook(BlockingQueue<Product> products) {
		this.products = products;
	}
	public void product(){
		Product product = new Product(productId ++ );
		System.out.println("生产了" + product);
		products.add(product);
	}
	
	public boolean isRest() {
		return rest;
	}
	public void setRest(boolean rest){
		this.rest = rest;
	}
	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				synchronized (this) {
					while(products.size() >= 10){
						System.out.println("有剩余产品,厨师休息…………");
						rest = true;
						wait();
					}
				}
				product();// 50ms生产一个
				TimeUnit.MILLISECONDS.sleep(50);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("停止生产!");
		}
	}
}
class Product{
	private int productId;
	Product(int productId){
		this.productId = productId;
	}
	public int getProductId() {
		return productId;
	}
	
	@Override
	public String toString() {
		return "产品" + productId;
	}
}
class Customer implements Runnable{
	private BlockingQueue<Product> products;
	private String name;
	private Cook cook;
	public Customer(Cook cook,BlockingQueue<Product> products, String name) {
		this.cook = cook;
		this.products = products;
		this.name = name;
	}

	public void consume(){
		try {
			Product product = products.take();
			System.out.println(name + " 消费" + product);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
		}
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				consume();// 500消费一个
				synchronized (cook) {
					if(products.size() == 0 && cook.isRest()){
						cook.setRest(false);
						cook.notifyAll();
						System.out.println("库存不够,厨师开始工作……");
					}
				}
				TimeUnit.MILLISECONDS.sleep(500);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("用户:" + name + "停止消费!");
		}
		
	}
}
public class Restaurant {
	private Cook cook;
	
	public Restaurant(Cook cook) {
		this.cook = cook;
	}

	public static void main(String[] args) throws InterruptedException {
		
		System.out.println("饭馆开门");
		ExecutorService exec = Executors.newCachedThreadPool();
		BlockingQueue<Product> products = new LinkedBlockingQueue<Product>();
		Cook cook = new Cook(products);
		Restaurant restaurant = new Restaurant(cook);
		exec.execute(cook);
		for(int i = 0; i < 5; i++){
			exec.execute(new Customer(cook,products, "用户" +  i));
		}
		
		TimeUnit.SECONDS.sleep(2);//模拟五秒
		exec.shutdownNow();
		System.out.println("饭馆关门");
	}

}

 

 Output:

 

饭馆开门

生产了产品0

用户0 消费产品0

生产了产品1

用户1 消费产品1

生产了产品2

用户2 消费产品2

生产了产品3

用户4 消费产品3

生产了产品4

用户3 消费产品4

生产了产品5

生产了产品6

生产了产品7

生产了产品8

生产了产品9

用户0 消费产品5

生产了产品10

用户1 消费产品6

生产了产品11

用户2 消费产品7

生产了产品12

用户4 消费产品8

生产了产品13

用户3 消费产品9

生产了产品14

生产了产品15

生产了产品16

生产了产品17

生产了产品18

生产了产品19

用户0 消费产品10

生产了产品20

用户1 消费产品11

生产了产品21

用户2 消费产品12

生产了产品22

用户4 消费产品13

生产了产品23

用户3 消费产品14

生产了产品24

有剩余产品,厨师休息…………

用户0 消费产品15

用户1 消费产品16

用户2 消费产品17

用户4 消费产品18

用户3 消费产品19

用户0 消费产品20

用户:用户2停止消费!

停止生产!

用户:用户1停止消费!

用户:用户0停止消费!

用户:用户3停止消费!

用户:用户4停止消费!

饭馆关门


 

1
3
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics