生产者和消费者是多线程经典的问题,生产者和消费者问题的核心是同步的问题,同步问题的核心是要保证同一个资源被多个线程并发访问时的完整性,常用的方法是采用信号或加锁机制,保证资源在任一时刻只能被一个线程访问。这一问题用java来实现的话主要有4种方式。1.wait()/notify();2.await()/signal(); 3.blockingQuene 4.PipedInputStream/pipedOutputStream
下面分别来实现。
1.利用wait()和notify()来实现
Wait()方法:当缓冲区已空/满时,生产者/消费者停止自己的执行,放弃锁,使自己处于等待状态,让其他线程执行。
Notify()方法:当生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态。
下面看看代码实现:
首先定义商店类:
package ConsumerAndProducerProblem;
?
import java.util.LinkedList;
?
/**
?* @author: zhuwei
?* @ClassName: 商店类
?* @Description: TODO
?* @Date: 下午3:58:01
?*/
public class Storage
{
?
? ? //定义仓库最大容量100
? ? private final int MAX_SIZE = 100;
? ? private LinkedList
定义生产者类
package ConsumerAndProducerProblem;
?
?
/**
?* @author: zhuwei
?* @ClassName: 生产者线程
?* @Description: TODO
?* @Date: 下午3:57:15
?*/
public class Consumer implements Runnable
{
?
? ? //消费商品数量
? ? private int number;
?
? ? private Storage storage;
?
?
? ? public void consume(int num)
? ? {
? ? ? try
? ? ? {
? ? ? ? ? storage.consume(num);
? ? ? } catch (Exception e)
? ? ? {
? ? ? ? ? // TODO Auto-generatedcatch block
? ? ? ? ? e.printStackTrace();
? ? ? }
? ? }
?
? ? public int getNumber()
? ? {
? ? ? return number;
? ? }
?
?
?
? ? public void setNumber(int number)
? ? {
? ? ? this.number = number;
? ? }
?
?
?
? ? public Storage getStorage()
? ? {
? ? ? return storage;
? ? }
?
?
?
? ? public void setStorage(Storage storage)
? ? {
? ? ? this.storage = storage;
? ? }
?
?
?
? ? @Override
? ? public void run()
? ? {
? ? ? // TODO Auto-generatedmethod stub
? ? ? consume(number);
? ? }
?
}
定义消费者类:
package ConsumerAndProducerProblem;
?
/**
?* @author: zhuwei
?* @ClassName: 消费者线程
?* @Description: TODO
?* @Date: 下午3:57:38
?*/
public class Producer implements Runnable
{
? ? //生产的商品数量
? ? private int number;
?
? ? private Storage storage;
?
? ? public void produce(int num)
? ? {
? ? ? try
? ? ? {
? ? ? ? ? storage.produce(num);
? ? ? } catch (Exception e)
? ? ? {
? ? ? ? ? // TODO Auto-generatedcatch block
? ? ? ? ? e.printStackTrace();
? ? ? }
? ? }
?
? ? public int getNumber()
? ? {
? ? ? return number;
? ? }
?
? ? public void setNumber(int number)
? ? {
? ? ? this.number = number;
? ? }
?
? ? public Storage getStorage()
? ? {
? ? ? return storage;
? ? }
?
? ? public void setStorage(Storage storage)
? ? {
? ? ? this.storage = storage;
? ? }
?
? ? @Override
? ? public void run()
? ? {
? ? ? // TODO Auto-generatedmethod stub
? ? ? produce(number);
? ? }
?
}
创建测试类:
package ConsumerAndProducerProblem;
?
public class Test
{
?
? ? public static void main(String[] args)
? ? {
? ? ? // TODO Auto-generatedmethod stub
? ? ? //仓库对象
? ? ? Storage storage = new Storage();
? ? ?
? ? ? //消费者对象
? ? ? Consumer c1 = new Consumer();
? ? ? c1.setNumber(10);
? ? ? c1.setStorage(storage);
? ? ? Consumer c2 = new Consumer();
? ? ? c2.set