• ArrayBlockingQueue 实现定时推送数据


    有界阻塞队列,内部使用数组存储元素,有2个常用构造方法:
    capacity表示容量大小,默认内部采用非公平锁
    public ArrayBlockingQueue(int capacity)
    capacity:容量大小,fair:内部是否是使用公平锁
    public ArrayBlockingQueue(int capacity, boolean fair)

    1.demo

    public class Demo {
        //推送队列
        static ArrayBlockingQueue<String> pushQueue = new ArrayBlockingQueue<String>(10000);
    
        static {
            //启动一个线程做真实推送
            new Thread(() -> {
                while (true) {
                    String msg;
                    try {
                        long starTime = System.currentTimeMillis();
                        //获取一条推送消息,此方法会进行阻塞,直到返回结果
                        msg = pushQueue.take();
                        long endTime = System.currentTimeMillis();
                        //模拟推送耗时
                        TimeUnit.MILLISECONDS.sleep(500);
    
                        System.out.println(String.format("[%s,%s,take耗时:%s],%s,发送消息:%s", starTime, endTime, (endTime - starTime), Thread.currentThread().getName(), msg));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    
        //推送消息,需要发送推送消息的调用该方法,会将推送信息先加入推送队列
        public static void pushMsg(String msg) throws InterruptedException {
            pushQueue.put(msg);
        }
    
        public static void main(String[] args) throws InterruptedException {
            for (int i = 1; i <= 5; i++) {
                String msg = "消息内容";
                //模拟耗时
                TimeUnit.SECONDS.sleep(i);
                Demo1.pushMsg(msg);
            }
        }
    }
    
    创建ArrayBlockingQueue时候需要制定容量大小,调用pushQueue.put将推送信息放入队列中,如果队列已
    满,此方法会阻塞。代码中在静态块中启动了一个线程,调用pushQueue.take();从队列中获取待推送的信息进行推送处理。
    注意:ArrayBlockingQueue如果队列容量设置的太小,消费者发送的太快,消费者消费的太慢的情况下,会导致队列空间满,
    调用put方法会导致发送者线程阻塞,所以注意设置合理的大小,协调好消费者的速度。

    2.

    package com...BlockingQueue;
    
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    import wfc.service.database.RecordSet;
    import wfc.service.database.SQL;
    import java.util.concurrent.*;
    
    
    @Component
    @EnableScheduling//可以在启动类上注解也可以在当前文件
    public class BlockingQueues {
    
        private static ExecutorService service = Executors.newFixedThreadPool(10);
        private static BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);
    //    private static RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();拒绝策略
    //    private static ExecutorService executorService = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, queue, handler);
    
        @Scheduled(cron = "0 0/1 * * * ?")//1分钟
        public void query(){
            doSting();
        }
    
        private static void doSting(){
    
            new Thread(new Runnable() {
                boolean flag = true;
                @Override
                public void run() {
    
                    System.out.println("开始扫描未推送的办件到BlockingQueue....");
                    String type = "0";
                    String insertSql = "select * from DANGAN_FJ where TYPE = ? ";
                    Object[] insertObject = new Object[] {type};
                    RecordSet rs = SQL.execute(insertSql,insertObject);
                    while (rs.next()){
                        String ST_FJ_ID = rs.getString("ST_FJ_ID");
                        try {
                            queue.put(ST_FJ_ID);
                        } catch (InterruptedException e) {
                            System.out.println("放入队列出异常...:"+e);
                            e.printStackTrace();
                        }
                    }
                    System.out.println("BlockingQueue队列里的办件--->:"+queue);
    
                    while (flag) {
                        service.execute(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    String ST_FJ_ID = queue.take();
                                    String updateSql = "update dangan_fj set type =-1 where st_fj_id = ? ";
                                    Object[] updateObject = new Object[]{ST_FJ_ID};
                                    RecordSet updateRs = SQL.execute(updateSql, updateObject);
                                    int number = updateRs.TOTAL_RECORD_COUNT;
                                    //影响行数
                                    System.out.println("办件过期更改影响行数:  " + number + "   办件编号为:" + ST_FJ_ID+"  处理线程:"+Thread.currentThread().getName());
    
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                        if(queue.isEmpty()){
                            flag =false;
                        }
                    }
                }
            },"").start();
    
        }
    
    
    }
  • 相关阅读:
    wc
    wbinfo
    wall -- 向所有人的终端发送消息
    w
    vt-is-UTF8
    vmstat
    vimtutor
    vim
    centos7
    Web 在线文件管理器学习笔记与总结(8)删除文件
  • 原文地址:https://www.cnblogs.com/lifan12589/p/13753672.html
Copyright © 2020-2023  润新知