• 生产者消费者模型


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

    生产者

    消费者

    缓冲队列

    缓冲队列要求:

    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

  • 相关阅读:
    MySQL读写分离技术
    MySQL主从复制与主主复制
    搭建MySQL高可用负载均衡集群
    CentOS7安装openjdk、tomcat和mysql流程介绍
    windows下 安装 rabbitMQ 及操作常用命令
    Python Twisted、Reactor
    数据结构(DataStructure)与算法(Algorithm)、STL应用
    RCE via XStream object deserialization && SECURITY-247 / CVE-2016-0792 XML reconstruction Object Code Inject
    IRC(Internet Relay Chat Protocol) Protocal Learning && IRC Bot
    phpcms /api/phpsso.php SQL Injection Vul
  • 原文地址:https://www.cnblogs.com/mu-tou-man/p/4840519.html
Copyright © 2020-2023  润新知