zoukankan      html  css  js  c++  java
  • 基于数组阻塞队列 ArrayBlockingQueue 的一个队列工具类

    java语言基于ArrayBlockingQueue 开发的一个根据特定前缀和后缀的队列。每天自动循环生成。

      1.定义队列基类 Cookie

      

    package com.bytter.util.queue;
    
    import java.util.Date;
    import java.util.concurrent.ArrayBlockingQueue;
    
    public class Cookie {
        private ArrayBlockingQueue<String> queue;
        private int cursor = 1;
        private Date date = new Date();
        private int maxPoolQueue = 500;
        private int mixPoolQueue = 100;
        
        public Cookie(int maxPoolQueue,int mixPoolQueue,Date date){
            this.maxPoolQueue=maxPoolQueue;
            this.mixPoolQueue=mixPoolQueue;
            this.date=date;
            this.queue = new ArrayBlockingQueue<String>(this.maxPoolQueue,true);
        }
        
        public Cookie(int maxPoolQueue,int mixPoolQueue,Date date, int cursor){
        	this.maxPoolQueue = maxPoolQueue;
        	this.mixPoolQueue = mixPoolQueue;
            this.date=date;
            this.cursor=cursor;
    		this.queue = new ArrayBlockingQueue<String>(this.maxPoolQueue,true);
        }
        
        public ArrayBlockingQueue<String> getQueue() {
    		return queue;
    	}
    
    	public Cookie setQueue(ArrayBlockingQueue<String> queue) {
    		this.queue = queue;
    		return this;
    	}
    
    	public int getCursor() {
    		return cursor;
    	}
    
    	public Cookie setCursor(int cursor) {
    		this.cursor = cursor;
    		return this;
    	}
    
    	public Date getDate() {
    		return date;
    	}
    
    	public Cookie setDate(Date date) {
    		this.date = date;
    		return this;
    	}
    
    	public int getMaxPoolQueue() {
    		return maxPoolQueue;
    	}
    
    	public Cookie setMaxPoolQueue(int maxPoolQueue) {
    		this.maxPoolQueue = maxPoolQueue;
    		return this;
    	}
    
    	public int getMixPoolQueue() {
    		return mixPoolQueue;
    	}
    
    	public Cookie setMixPoolQueue(int mixPoolQueue) {
    		this.mixPoolQueue = mixPoolQueue;
    		return this;
    	}
    	
    }
    

      

      2.QueueUtil 队列工具类,用于获取队列中的值(主要是获取付款的单号==)

    package com.bytter.util.queue;
    
    import java.util.Date;
    import java.util.List;
    import java.util.concurrent.ConcurrentHashMap;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import com.bytter.framework.persistence.dao.IBaseDAO;
    import com.bytter.util.AppContextUtil;
    import com.bytter.util.DateUtil;
    /**
     * 
     * @author
     * May 6, 2019 10:35:39 AM
     * @version
     */
    public class QueueUtil{
    	
    	private static Logger log = LogManager.getLogger(QueueUtil.class);	
    	protected static IBaseDAO baseDao = null;
    	private static ConcurrentHashMap<String, Cookie> queueMap = new ConcurrentHashMap<String, Cookie>();
    	
    	private static class SingletonClassInstance{
            private static final QueueUtil instance=new QueueUtil();
        }
         
        private QueueUtil(){}
         
        public static QueueUtil getInstance(){
            return SingletonClassInstance.instance;
        }
    	
    	/**
    	 * 调用事例: QueueUtil.getInstance().getSequence(SequenceEnum.BIS_EXC)
    	 * @param sequenceEnum
    	 * @return
    	 * @throws InterruptedException
    	 */
    	@SuppressWarnings("unchecked")
    	public String getSequence(SequenceEnum sequenceEnum) throws InterruptedException{
    		String value = "";
    		String key = sequenceEnum.getTableName()+"_"+sequenceEnum.getFieldName();
    		Cookie cookie = queueMap.get(key);
    		value  = cookie.getQueue().take();
    		String returnValue = sequenceEnum.getPrefix()+DateUtil.dateToStr(sequenceEnum.getDateFormat(), new Date());
    		for (int i = 0; i < sequenceEnum.getSequenceLength()-value.length(); i++) {
    			returnValue += "0";
    		}
    		returnValue += value;
    		log.info("取出的单号:"+returnValue);
    		return returnValue;
    	}
    	
    	public void initQueue() {
    		putAllMap();
    		Thread thread = new Produce(queueMap);
    		thread.setName("QueueUtil_Produce");
    		thread.start();
    	}
    
    	private static void putAllMap() {
    		queueMap.clear();
    		int curor = 1;
    		log.info("-----开始加载队列 -------");
    		for (SequenceEnum sequenceEnum : SequenceEnum.values()){
    			String key = sequenceEnum.getTableName()+"_"+sequenceEnum.getFieldName();
    			//同一天但是系统重启或者宕机的情况时,游标重置为1.此时需要查询表中最大的值并且置游标值+1
    			String sql="SELECT MAX("+sequenceEnum.getFieldName()+") FROM "+sequenceEnum.getTableName()+" WHERE "+sequenceEnum.getFieldName()+" LIKE '"+sequenceEnum.getPrefix()+"%'";
    			List list = baseDao.search_sql(null, sql, "", "", null);
    			if(list != null && list.size() >0 && list.get(0) != null){
    				String no = list.get(0).toString();
    				//单号,自增。
    				String count = no.substring(no.length()-sequenceEnum.getSequenceLength());
    				String date = no.replaceAll(count, "").replaceAll(sequenceEnum.getPrefix(), "");
    				/*if(date.equals(DateUtil.dateToStr(sequenceEnum.getDateFormat(), new Date()))){
    					curor = Integer.parseInt(count) + 1;
    				}*/
    			}
    			log.info("加载队列 :table=="+sequenceEnum.getTableName()+" field=="+sequenceEnum.getFieldName()+" 游标=="+curor);
    			queueMap.put(key, new Cookie(sequenceEnum.getMaxSeqSize(),sequenceEnum.getMinSeqSize(),new Date(),curor));
    		}
    		log.info("-----队列加载完毕 -------");
    	}
    	
    	static{
    		baseDao = AppContextUtil.getBean("baseDao");
    		//第一次调用时开启队列
    		//initQueue(); 
    	}
    
    	
    }
    

      3.生产者线程类

      

    package com.bytter.util.queue;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ConcurrentHashMap;
    
    import com.bytter.util.DateUtil;
    
    public class Produce extends Thread{
        private ConcurrentHashMap<String, Cookie> queueMap;
        public Produce(ConcurrentHashMap<String, Cookie> queueMap){
            this.queueMap=queueMap;
        }
        public void run(){
        	ArrayBlockingQueue<String> queue;
        	int mixSize;
        	int curor;
        	Cookie cookie;
        	Date date;
        	Map.Entry<String,Cookie> entry;
        	Iterator<Map.Entry<String,Cookie>> iteratorMap;
        	while (true) {
        		iteratorMap = queueMap.entrySet().iterator();
                while (iteratorMap.hasNext()){
                    entry = iteratorMap.next();
                    cookie = entry.getValue();
        			queue = cookie.getQueue();
        			mixSize = cookie.getMixPoolQueue();
        			curor = cookie.getCursor();
        			date = cookie.getDate();
        			//新的一天,游标开始重置
        			if(!DateUtil.dateToStr("yyyy-MM-dd", new Date()).equals(DateUtil.dateToStr("yyyy-MM-dd", date))){
        				curor = 1;
        				queue.clear();
        				date = new Date();
        				System.out.println("重置游标时间===="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        			}
        			
        			//offer 在填满后返回false
        			if(queue.size() < mixSize){
        				while (queue.offer(curor + "")) {
        					curor++;
        				}
        			}
        			cookie.setQueue(queue).setCursor(curor).setDate(date);
        			queueMap.put(entry.getKey(),cookie);
                }
    		}
        }
    }
    

      4.自定义的生成单号的规则枚举类

      

    package com.bytter.util.queue;
    public enum SequenceEnum{
    		/**
    		 * 付款指令编码 yyMMdd000001
    		 * @return 
    		 */
    		BIS_EXC("",6, "BIS_EXC", "VOUCHER_NO", "yyMMdd",500,100),
    		/**
    		 * 付款单号
    		 * @return 
    		 */
    		PAYMENT_BILL_NO("P",7, "T_BIS_PAYMENT_INFO", "BILL_CODE", "yyMMddHHmmss",500,100),
    		
    		;
    		
    		
    		/**
    		 * 流水号前缀
    		 */
    		private String prefix;
    
    		/**
    		 * 流水号数字部分长度
    		 */
    		private Integer sequenceLength;
    		/**
    		 * 业务表名
    		 */
    		private String tableName;
    		/**
    		 * 业务表中的字段名
    		 */
    		private String fieldName;
    		/**
    		 * 日期格式化模板
    		 */
    		private String dateFormat;
    		
    		/**
    		 * 队列最大的长度
    		 */
    		private int maxSeqSize;
    		/**
    		 * 队列最小长度
    		 */
    		private int minSeqSize;
    		
    		
    		/**
    		 * @param prefix           流水号前缀
    		 * @param sequenceLength   流水号自增长长度
    		 * @param tableName        表名
    		 * @param fieldName        字段名
    		 * @param dateFormat       日期格式化模板
    		 */
    		SequenceEnum(String prefix, Integer sequenceLength, String tableName, String fieldName,String dateFormat,int maxSeqSize,int minSeqSize) {
    			this.prefix = prefix;
    			this.sequenceLength = sequenceLength;
    			this.tableName = tableName;
    			this.fieldName = fieldName;
    			this.dateFormat = dateFormat;
    			this.maxSeqSize = maxSeqSize;
    			this.minSeqSize = minSeqSize;
    		}
    		
    		/**
    		 * @param prefix           流水号前缀
    		 * @param sequenceLength   流水号自增长长度
    		 * @param tableName        表名
    		 * @param fieldName        字段名
    		 * @param dateFormat       日期格式化模板
    		 */
    		SequenceEnum(Integer sequenceLength, String tableName, String fieldName,String dateFormat) {
    			this.sequenceLength = sequenceLength;
    			this.tableName = tableName;
    			this.fieldName = fieldName;
    			this.dateFormat = dateFormat;
    		}
    		
    		public String getPrefix() {
    			return prefix;
    		}
    		public void setPrefix(String prefix) {
    			this.prefix = prefix;
    		}
    		public Integer getSequenceLength() {
    			return sequenceLength;
    		}
    		public void setSequenceLength(Integer sequenceLength) {
    			this.sequenceLength = sequenceLength;
    		}
    		public String getTableName() {
    			return tableName;
    		}
    		public void setTableName(String tableName) {
    			this.tableName = tableName;
    		}
    		public String getFieldName() {
    			return fieldName;
    		}
    		public void setFieldName(String fieldName) {
    			this.fieldName = fieldName;
    		}
    
    		public String getDateFormat() {
    			return dateFormat;
    		}
    
    		public void setDateFormat(String dateFormat) {
    			this.dateFormat = dateFormat;
    		}
    
    		public int getMaxSeqSize() {
    			return maxSeqSize;
    		}
    
    		public void setMaxSeqSize(int maxSeqSize) {
    			this.maxSeqSize = maxSeqSize;
    		}
    
    		public int getMinSeqSize() {
    			return minSeqSize;
    		}
    
    		public void setMinSeqSize(int minSeqSize) {
    			this.minSeqSize = minSeqSize;
    		}
    
    	}
    

      5.测试相关类

        1> 消费者线程

        

    package com.bytter.util.queue;
    
    public class 	 implements Runnable{
    	
    	
    	
        public void run(){
    		try {
    			for (int i = 0; i < 200; i++) {
    				Thread.sleep(Long.valueOf((long) (Math.random()*10*300)));
    //				System.out.println(Thread.currentThread().getName());
    				System.out.println(Thread.currentThread().getName()+"==="+SequenceUtilTest.getInstance().getSequence(SequenceEnum.BIS_EXC));
    			}
    		} catch (Exception e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
        }
    }
    

        2>测试main 方法

    package com.bytter.util.queue;
    
    public class tests {
    
    	
    	public static void main(String[] args) throws InterruptedException {
    		new Thread(new Consume()).start();
    		new Thread(new Consume()).start();
    		new Thread(new Consume()).start();
    		new Thread(new Consume()).start();
    		new Thread(new Consume()).start();
    //		new Thread(new Consume()).start();
    //		new Thread(new Consume()).start();
    //		new Thread(new Consume()).start();
    //		new Thread(new Consume()).start();
    //		new Thread(new Consume()).start();
    	}
    }
    

      

  • 相关阅读:
    多线程实践
    sql你server,mysql,oracle的分页语句
    BS与CS的联系与区别
    EJB与JAVA BEAN的区别
    Struts2.0 xml文件的配置(package,namespace,action)
    Q 51~60
    Q 41~50
    列表推导式
    Q 31~40
    Q 21~30
  • 原文地址:https://www.cnblogs.com/chinazhou-wang/p/11274970.html
Copyright © 2011-2022 走看看