码迷,mamicode.com
首页 > 其他好文 > 详细

生产者消费者模型

时间:2015-09-26 12:02:26      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

生产者消费者模型当中有三个实体,他们分别是:

生产者

消费者

缓冲队列

 

缓冲队列要求:

1.当缓冲队列为空时,不能往外取

2.当缓冲队列为满时,不能继续往里添加

 

对于缓冲队列的选择,可以选择线程安全的和线程非安全的.

线程安全的类 ,指的是类内共享的全局变量的访问必须保证是不受多线程形式影响的。如果由于多线程的访问(比如修改、遍历、查看)而使这些变量结构被破坏或者针对这些变量操作的原子性被破坏,则这个类就不是线程安全的。

线程不安全的包括:ArrayList.LinkedList等

线程安全的包括:LinkedBlockingQueue,ArrayBlockingQueue等

 

下面我们用线程不安全的LinkedList进行实验,看代码

缓冲队列内要加入的元素类

public class Task
{

}

缓存队列类

public class Storage
{
    private final int MAX_SIZE = 4;
    Queue<Task> taskQueue = new LinkedList<Task>();

    public void Produce()
    {
        synchronized (this.taskQueue)
        {
            //如果队列已满 则不能继续添加任务 用wait()停止自己的线程 让其他线程进行
            while (taskQueue.size() >= MAX_SIZE)
            {
                System.out.println("队列满了,无法继续放入任务");
                try
                {
                    taskQueue.wait();
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            //如果队列不满 添加任务
            taskQueue.add(new Task());
            System.out.println("添加了一个任务,队列内剩余任务数量为:" + taskQueue.size());
            //
            taskQueue.notifyAll();
        }
    }

    public void Consume()
    {
        synchronized (this.taskQueue)
        {
            //如果仓内已空 则不能继续销售 用wait()停止自己的线程 让其他线程进行
            while (taskQueue.size() <= 0)
            {
                System.out.println("队列空了,没有任务需要执行");
                try
                {
                    taskQueue.wait();
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            //如果队列不空 则移除队头
            taskQueue.remove();
            System.out.println("取出了一个任务,队列内剩余任务数量为:" + taskQueue.size());
            taskQueue.notifyAll();
        }
    }
}

生产者类

public class Producer extends Thread
{
    private Storage st;

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

    public void run()
    {
        pro(st);
    }

    public void pro(Storage st)
    {
        st.Produce();
    }
}

消费者类

public class Consumer extends Thread
{
    private Storage st;

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

    public void run()
    {
        con(st);
    }

    public void con(Storage st)
    {
        st.Consume();
    }
}

主函数

public class ProConTest
{
    public static void main(String[] args)
    {
        Storage st = new Storage();
        Producer pr1 = new Producer(st);
        Producer pr2 = new Producer(st);
        Producer pr3 = new Producer(st);
        Producer pr4 = new Producer(st);
        Producer pr5 = new Producer(st);
        Consumer co1 = new Consumer(st);
        Consumer co2 = new Consumer(st);
        Consumer co3 = new Consumer(st);
        Consumer co4 = new Consumer(st);
        Consumer co5 = new Consumer(st);
        Consumer co6 = new Consumer(st);
        pr1.start();
        pr2.start();
        co1.start();
        co2.start();
        co3.start();
        pr3.start();
        pr4.start();
        pr5.start();
        co4.start();
        co5.start();
        co6.start();

    }
}

 

下面看一下跑出的结果:

添加了一个任务,队列内剩余任务数量为:1
添加了一个任务,队列内剩余任务数量为:2
取出了一个任务,队列内剩余任务数量为:1
取出了一个任务,队列内剩余任务数量为:0
添加了一个任务,队列内剩余任务数量为:1
取出了一个任务,队列内剩余任务数量为:0
队列空了,没有任务需要执行
队列空了,没有任务需要执行
队列空了,没有任务需要执行
添加了一个任务,队列内剩余任务数量为:1
取出了一个任务,队列内剩余任务数量为:0
队列空了,没有任务需要执行
队列空了,没有任务需要执行
添加了一个任务,队列内剩余任务数量为:1
取出了一个任务,队列内剩余任务数量为:0
队列空了,没有任务需要执行

 

生产者消费者模型

标签:

原文地址:http://www.cnblogs.com/mu-tou-man/p/4840519.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!