多线程经典问题之生产者消费者问题的JAVA实现

生产者消费者问题作为多线程中helloworld,是每个多线程开发人员入门必须掌握的。生产者消费者问题在开发当中应用广泛,如最常接触的线程池实现,多种阻塞消息队列中。下面介绍一下用java.util.concurrent.BlockingQueue实现和自己编写一个Storage实现简单部分类似BlockingQueue的功能。

 

public class ProducerAndConsumerImplByBlockingQueue {


    public static void main(String[] args) {
        //Storage store = new Storage();
        BlockingQueue<String> queue = new LinkedBlockingQueue<String>(20);//定义        BlockingQueue的大小为20

        Thread t1 = new Thread(new Producer1(queue));
        Thread t2 = new Thread(new Consumer1(queue));
        t1.start();
        t2.start();
    }
}

/**
 * 生产者线程
 * @author YZJ
 *
 */
class Producer1 implements Runnable {

    private BlockingQueue<String> queue;

    public Producer1(BlockingQueue<String> queue){
        this.queue = queue;
    }


    @Override
    public void run() {
        int i = 1;
        while(true){
            try {
                System.out.println("生产产品:"+i);
                queue.put("产品"+i++);
                Thread.sleep(200);//线程睡眠时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}


/**
 * 消费者线程
 * @author YZJ
 *
 */
class Consumer1 implements Runnable {


    private BlockingQueue<String> queue;

    public Consumer1(BlockingQueue<String> queue){
        this.queue = queue;
    }

    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println("消费产品:"+queue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

 

 

 

LinkedBlockingQueue用链表的方式实现FIFO,采用ReentrantLock进行同步,关于ReentrantLock机制大家可自行查阅相关文章,作者在后续中也会对ReentrantLock原理进行简单分析。除LinkedBlockingQueue以外,BlockingQueue的常用实现还有ArrayBlockingArray,内部采用数组实现,类似于LinkedList和ArrayList的关系。其他实现还有PriorityBlocingQueue,SynchronousQueue。PriorityBlocingQueue于采用自然排序或自定义comparator实现排序而非FIFO;SynchronousQueue则是实现一放一取的队列。

 

2.自定义Storage

 

 

public class ProducerAndConsumer {


    public static void main(String[] args) {
        Storage store = new Storage();
        Thread t1 = new Thread(new Producer(store));
        Thread t2 = new Thread(new Consumer(store));
        t1.start();
        t2.start();
    }


}




/**
 * 生产者线程
 * @author YZJ
 *
 */
class Producer implements Runnable {

    private Storage storage;

    public Producer(Storage storage){
        this.storage = storage;
    }

    @Override
    public void run() {
        int i = 1;
        while(true){
            storage.push("产品"+i++);

        }

    }



}


/**
 * 消费者线程
 * @author YZJ
 *
 */
class Consumer implements Runnable {


    private Storage storage;

    public Consumer(Storage storage){
        this.storage = storage;
    }

    @Override
    public void run() {
        while(true){
            storage.pop();
        }
    }

}


/**
 * 阻塞队列,存放产品
 * @author YZJ
 *
 */
class Storage{

    private List<String> list = new ArrayList<String>();


    public void push(String product){
        synchronized(this){
            list.add(product);
            System.out.println("生产产品:"+product);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
// TODO Auto-generated catch block
                e1.printStackTrace();
            }
            if(list.size()==20){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.notify();
        }

    }

    public void pop(){
        synchronized(this){
            if(list.size()>0){
                System.out.println("消费产品:"+list.get(0));
                list.remove(0);
            }else{
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.notify();
        }
    }

    public List<String> getList(){
        return list;
    }
}

 

 

 

 

 

Storage同样采用FIFO策略,简单实现阻塞队列,若需要更改策略,可修改pop中提取策略即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值