`

多线程模拟生产者消费者关系

阅读更多

在现实应用中,很多时候都需要让多个线程按照一定的次序来访问共享资源,例如,经典的生产者和消费者问题。

仓库中没有产品时,消费者要等待生产者生产产品;当仓库满时,生产者要等待消费者消费产品;在仓库中有产品但

未满时,消费者可以消费产品,生产者可以生产产品。可以采用循环检测的方法来实现,但是可以利用提供的wait(),

notify(),notifyAll()来更好的处理。

 

共享资源:

/**
 * 文件:Resoures.java
 * 描述:TODO
 * 作者:luckystar2008
 * 日期:2012-1-10
 */
package thread.product.customer.multiple;

/**
 * @author luckystar2008
 *
 */
public class Resoures {
	private char[] cArr = new char[5]; //模拟仓库,存放5个字符
	private int index = 0; //信号量,初始值为0
	
	public synchronized void push(char c) {
		if (index == cArr.length) { //仓库已满
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		cArr[index] = c;
		index++;
		notify();
	}
	
	public synchronized  char pop() {
		if (index == 0) { //仓库是空的,等待生产者生产产品
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		index--;
		notify();
		return cArr[index];
	}
}

 

生产者:

/**
 * 文件:Productor.java
 * 描述:模拟生产者
 * 作者:luckystar2008
 * 日期:2012-1-10
 */
package thread.product.customer.multiple;

/**
 * @author luckystar2008
 *
 */
public class Productor extends Thread{
	private Resoures r ;
	
	public Productor(Resoures r) {
		this.r = r;
	}
	
	public void run() {
		for (int i=0;i<5;i++) {
			char c = (char)(Math.random()*26+'A');
			System.out.println("Push element " + c);
			r.push(c);
			try {
				Thread.sleep((long)Math.random()*3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

 

模拟消费者:

/**
 * 文件:Consumer.java
 * 描述:模拟消费者
 * 作者:luckystar2008
 * 日期:2012-1-10
 */
package thread.product.customer.multiple;

/**
 * @author luckystar2008
 *
 */
public class Consumer extends Thread{
	private Resoures r;
	
	public Consumer(Resoures r) {
		this.r =r ;
	}
	
	public void run() {
		for (int i=0;i<5;i++) {
			char c = r.pop();
			System.out.println("Pop element " + c);
			try {
				Thread.sleep((long)Math.random()*3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

 

测试:

/**
 * 文件:Test.java
 * 描述:测试
 * 作者:luckystar2008
 * 日期:2012-1-10
 */
package thread.product.customer.multiple;

/**
 * @author luckystar2008
 * 生产者和消费者可以同时生产或消费多个产品。
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Resoures r = new Resoures();
		Productor p = new Productor(r);
		Consumer c = new Consumer(r);

		c.start();
		p.start();
	}

}

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics