zoukankan      html  css  js  c++  java
  • ArrayBlockingQueue的使用案例:

    ArrayBlockingQueue的介绍:

    ArrayBlockingQueue,顾名思义:基于数组的阻塞队列。数组是要指定长度的,所以使用ArrayBlockingQueue时必须指定长度,也就是它是一个有界队列。

    它实现了BlockingQueue接口,有着队列、集合以及阻塞队列的所有方法,

    他有三个构造方法:

    并没有无参构造,所以必须要初始化长度,不让他变成一个无边界的数据队列,可能会存在内存过大的问题

    内部实现了ReentrantLock锁,所以线程是安全的,

    使用场景,异步队列发送邮件:

    首先封装mail对象进queue队列:

    public class Email implements Serializable {
        private static final long serialVersionUID = 1L;
        //必填参数
        private String[] email;//接收方邮件
        private String subject;//主题
        private String content;//邮件内容
        //选填
        private String template;//模板
        private HashMap<String, String> kvMap;// 自定义参数
        
        
        
        public Email() {
            super();
        }
        
        public Email(String[] email, String subject, String content, String template,
                HashMap<String, String> kvMap) {
            super();
            this.email = email;
            this.subject = subject;
            this.content = content;
            this.template = template;
            this.kvMap = kvMap;
        }
    
    
        public String[] getEmail() {
            return email;
        }
        public void setEmail(String[] email) {
            this.email = email;
        }
        public String getSubject() {
            return subject;
        }
        public void setSubject(String subject) {
            this.subject = subject;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
        public String getTemplate() {
            return template;
        }
        public void setTemplate(String template) {
            this.template = template;
        }
        public HashMap<String, String> getKvMap() {
            return kvMap;
        }
        public void setKvMap(HashMap<String, String> kvMap) {
            this.kvMap = kvMap;
        }
    }

    然后写一个MailQueue:

    package com.itstyle.mail.common.queue;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    import com.itstyle.mail.common.model.Email;
    /**
    
    public class MailQueue {
         //队列大小
        static final int QUEUE_MAX_SIZE   = 1000;
    
        //static BlockingQueue<Email> blockingQueue = new LinkedBlockingQueue<Email>(QUEUE_MAX_SIZE);
    
        static ArrayBlockingQueue<Email> blockingQueue=new ArrayBlockingQueue<Email>(100);
        
        /**
         * 私有的默认构造子,保证外界无法直接实例化
         */
        private MailQueue(){};
        /**
         * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例
         * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
         */
        private static class SingletonHolder{
            /**
             * 静态初始化器,由JVM来保证线程安全
             */
            private  static MailQueue queue = new MailQueue();
        }
        //单例队列
        public static MailQueue getMailQueue(){
            return SingletonHolder.queue;
        }
        //生产入队
        public  void  produce(Email mail) throws InterruptedException {
            blockingQueue.put(mail);
        }
        //消费出队
        public  Email consume() throws InterruptedException {
            return blockingQueue.take();
        }
        // 获取队列大小
        public int size() {
            return blockingQueue.size();
        }
    }

    里面包括了消费和创建的方法:

     //生产入队
        public  void  produce(Email mail) throws InterruptedException {
            blockingQueue.put(mail);
        }
        //消费出队
        public  Email consume() throws InterruptedException {
            return blockingQueue.take();
        }

    使用静态内部类的方法,保证单利模式

    消费队列:

    package com.itstyle.mail.common.queue;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import com.itstyle.mail.common.model.Email;
    import com.itstyle.mail.service.IMailService;
    
    @Component
    public class ConsumeMailQueue {
        private static final Logger logger = LoggerFactory.getLogger(ConsumeMailQueue.class);
        @Autowired
        IMailService mailService;
        
        @PostConstruct
        public void startThread() {
            ExecutorService e = Executors.newFixedThreadPool(2);// 两个大小的固定线程池
            e.submit(new PollMail(mailService));
            e.submit(new PollMail(mailService));
        }
    
        class PollMail implements Runnable {
            IMailService mailService;
    
            public PollMail(IMailService mailService) {
                this.mailService = mailService;
            }
    
            @Override
            public void run() {
                while (true) {
                    try {
                        Email mail = MailQueue.getMailQueue().consume();
                        if (mail != null) {
                            logger.info("剩余邮件总数:{}",MailQueue.getMailQueue().size());
                            mailService.send(mail);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        @PreDestroy
        public void stopThread() {
            logger.info("destroy");
        }
    }

    这种从线程池获取消费线程来执行,这个里面是一个多线程环境,为什么可以保证线程安全呢,是由于ArrayBlokcingQueue实现了reentranlock来实现的,

     在这里将需要发送邮件的信息添加到队列中去.

    如果需要判断是否满了,就需要使用offer方法,不是使用reminingkey方法:

    可以参看下面文字:https://www.xttblog.com/?p=3686,这个大佬写的博客园

  • 相关阅读:
    leetcode 155. Min Stack 、232. Implement Queue using Stacks 、225. Implement Stack using Queues
    leetcode 557. Reverse Words in a String III 、151. Reverse Words in a String
    leetcode 153. Find Minimum in Rotated Sorted Array 、154. Find Minimum in Rotated Sorted Array II 、33. Search in Rotated Sorted Array 、81. Search in Rotated Sorted Array II 、704. Binary Search
    leetcode 344. Reverse String 、541. Reverse String II 、796. Rotate String
    leetcode 162. Find Peak Element
    leetcode 88. Merge Sorted Array
    leetcode 74. Search a 2D Matrix 、240. Search a 2D Matrix II
    Android的API版本和名称对应关系
    spring 定时任务执行两次解决办法
    解析字符串为泛型的方法
  • 原文地址:https://www.cnblogs.com/xiufengchen/p/10863414.html
Copyright © 2011-2022 走看看