public 
class TestFactory {
	public static void main(String[] args) {
		List<Integer> storage = new ArrayList<>();
		BaseRole p1 = new Provider("p1", storage);
		BaseRole p2 = new Provider("p2", storage);
		BaseRole p3 = new Provider("p3", storage);
		BaseRole c1 = new Consumer("c1", storage);
		BaseRole c2 = new Consumer("c2", storage);
		BaseRole c3 = new Consumer("c3", storage);
		
		p1.start();
		c1.start();
//		p2.start();
		c2.start();
//		p3.start();
//		c3.start();
	}
}
class BaseRole extends Thread {
	private List<Integer> storage;
	private String name;
	protected int count = 0;
	public BaseRole(String name, List<Integer> storage) {
		super();
		this.name = name;
		this.setStorage(storage);
	}
	protected void say(String msg) {
		System.out.println(name + ": " + msg);
		System.out.println("库存状况: " + this.storage + " = " + this.storage.size());
	}
	
	protected void business() throws Exception {
		
	}
	public List<Integer> getStorage() {
		return storage;
	}
	public void setStorage(List<Integer> storage) {
		this.storage = storage;
	}
	@Override
	public void run() {
		while (true) {
			try {
				synchronized (this.getStorage()) {
					business();
					// 打印输出太快,每执行一次操作都停一下
					Thread.sleep(1000);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
class Provider extends BaseRole {
	
	private AtomicInteger seq = new AtomicInteger();
	public Provider(String name, List<Integer> storage) {
		super(name, storage);
	}
	protected void business() throws Exception {
		int num = seq.incrementAndGet();
		if (this.getStorage().size() >= 10) {
			say("===============> 库存足够,不再生产");
			// 不能用sleep,因为sleep不会释放锁
			this.getStorage().wait(1000);
		} else {
			this.getStorage().add(num);
			say("生产了..." + num + "产品");
			this.getStorage().notifyAll();
		}
	}
}
class Consumer extends BaseRole {
	public Consumer(String name, List<Integer> storage) {
		super(name, storage);
	}
	protected void business() throws Exception {
		if (this.getStorage().size() <= 0) {
			say("================> 库存为0,等待");
			this.getStorage().wait(2000);
		} else {
			Integer remove = this.getStorage().remove(0);
			say("消费了: " + remove + "产品,共消费" + (++this.count));
			this.getStorage().notifyAll();
		}
	}
}