/*@author shijin * 生产者与消费者模型中要保证以下几点* 同一时间内只能有一个生产者生产 生产方法加锁sychronized * 同一时间内只能有一个消费者消费 消费方法加锁sychronized * 生产者生产的同时消费者不能消费 生产方法加锁sychronized * 消费者消费的同时生产者不能生产 消费方法加锁sychronized * 共享空间空时消费者不能继续消费 消费前循环判断是否为空空的话将该线程wait释放锁允许其他同步方法执行* 共享空间满时生产者不能继续生产 生产前循环判断是否为满满的话将该线程wait释放锁允许其他同步方法执行*/
//主类class ProducerConsumer { public static void main(String[] args)
{ StackBasket s = new StackBasket()Producer p = new Producer(s)Consumer c = new Consumer(s)Thread tp = new Thread(p)Thread tc = new Thread(c)tpstart()tcstart()}
// class Mantou { private int id
Mantou(int id){ thisid = id}
public String toString(){ return Mantou + id}
//共享栈空间class StackBasket { Mantou sm[] = new Mantou[]int index =
/** * show 生产方法
* show 该方法为同步方法持有方法锁* show 首先循环判断满否满的话使该线程等待释放同步方法锁允许消费* show 当不满时首先唤醒正在等待的消费方法但是也只能让其进入就绪状态* show 等生产结束释放同步方法锁后消费才能持有该锁进行消费* @param m 元素* @return 没有返回值*/
public synchronized void push(Mantou m){ try{ while(index == smlength){ Systemoutprintln(!!!!!!!!!生产满了!!!!!!!!!)thiswait()} thisnotify()}catch(InterruptedException e){ eprintStackTrace()}catch(IllegalMonitorStateException e){ eprintStackTrace()}
sm[index] = mindex++Systemoutprintln(生产了 + m + 共 + index + 个馒头)}
/** * show 消费方法* show 该方法为同步方法持有方法锁* show 首先循环判断空否空的话使该线程等待释放同步方法锁允许生产* show 当不空时首先唤醒正在等待的生产方法但是也只能让其进入就绪状态* show 等消费结束释放同步方法锁后生产才能持有该锁进行生产* @param b true 表示显示false 表示隐藏* @return 没有返回值*/ public synchronized Mantou pop(){ try{ while(index == ){ Systemoutprintln(!!!!!!!!!消费光了!!!!!!!!!)thiswait()} thisnotify()}catch(InterruptedException e){ eprintStackTrace()}catch(IllegalMonitorStateException e){ eprintStackTrace()} index——Systemoutprintln(消费了—— + sm[index] + 共 + index + 个馒头)return sm[index]}
class Producer implements Runnable { StackBasket ss = new StackBasket()Producer(StackBasket ss){ thisss = ss}
/** * show 生产进程
*/ public void run(){ for(int i = i < i++){ Mantou m = new Mantou(i)sspush(m)// Systemoutprintln(生产了 + m + 共 + ssindex + 个馒头)// 在上面一行进行测试是不妥的对index的访问应该在原子操作里因为可能在push之后此输出之前又消费了会产生输出混乱try{ Threadsleep((int)(Mathrandom()*))}catch(InterruptedException e){ eprintStackTrace()}
class Consumer implements Runnable { StackBasket ss = new StackBasket()Consumer(StackBasket ss){ thisss = ss}
/** * show 消费进程
*/ public void run(){ for(int i = i < i++){ Mantou m = sspop()// Systemoutprintln(消费了—— + m + 共 + ssindex + 个馒头)// 同上 在上面一行进行测试也是不妥的对index的访问应该在原子操作里因为可能在pop之后此输出之前又生产了会产生输出混乱try{ Threadsleep((int)(Mathrandom()*))}catch(InterruptedException e){ eprintStackTrace()}