• 生产者消费者模型


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

    生产者

    消费者

    缓冲队列

    缓冲队列要求:

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

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

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

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

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

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

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

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

    public class Task
    {
    
    }

    生产者类

    class Producer implements Runnable
    {
        private final Queue<Task> queue;
        private final static int MAX_SIZE = 2;
    
        Producer(Queue<Task> q)
        {
            queue = q;
        }
    
        public void run()
        {
            synchronized (queue)
            {
                //如果缓冲区满,该线程释放queue锁,等待
                while (queue.size() >= MAX_SIZE)
                {
                    try
                    {
                        queue.wait();
                    }
                    catch (InterruptedException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //如果缓冲区不满,则继续添加任务
                queue.add(new Task());
                System.out.println("增加了一个任务,当前任务总数为" + queue.size());
                //添加任务以后,通知所有处于等待状态的线程
                queue.notifyAll();
            }
        }
    }

    消费者类

    class Consumer implements Runnable
    {
        private final Queue<Task> queue;
    
        Consumer(Queue<Task> q)
        {
            queue = q;
        }
    
        public void run()
        {
            synchronized (queue)
            {
                //如果缓冲区内为空,消费者释放queue对象锁,处于等待状态
                while (queue.size() <= 0)
                {
                    try
                    {
                        queue.wait();
                    }
                    catch (InterruptedException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //如果缓冲区不为空,消费者将队首元素取走
                queue.remove();
                System.out.println("执行了一个任务,剩余任务总数为" + queue.size());
                //取走后通知所有处于等待状态的线程
                queue.notifyAll();
            }
        }
    }

    主函数类

    class Setup
    {
        public static void main(String args[])
        {
            Queue q = new LinkedList();
            Producer p = new Producer(q);
            Producer p1 = new Producer(q);
            Producer p2 = new Producer(q);
            Producer p3 = new Producer(q);
            Consumer c1 = new Consumer(q);
            Consumer c2 = new Consumer(q);
            new Thread(p).start();
            new Thread(p1).start();
            new Thread(p2).start();
            new Thread(c1).start();
            new Thread(c2).start();
        }
    }

    执行结果:

    增加了一个任务,当前任务总数为1
    增加了一个任务,当前任务总数为2
    执行了一个任务,剩余任务总数为1
    增加了一个任务,当前任务总数为2
    执行了一个任务,剩余任务总数为1

  • 相关阅读:
    数据库高并发
    Syslog+Fluentd+InfluxDB日志收集系统搭建
    EFK Stack容器部署
    Logstash过滤插件
    Collectd+InfluxDB+Grafana监控系统搭建
    Collectd基本使用
    Haproxy配置详解
    Kafka基本使用
    HDU-2087 剪花布条 字符串问题 KMP算法 查匹配子串
    POJ-2752 Seek the Name, Seek the Fame 字符串问题 KMP算法 求前后缀串相同数木
  • 原文地址:https://www.cnblogs.com/mu-tou-man/p/4840519.html
Copyright © 2020-2023  润新知