定时任务/线程排队

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。定时任务/线程排队,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

/**
 * 定时任务类
 * 每天0点取出数据实例化道数据库中
 */
@Component
public class MyJob {
    @Resource
    private RedisTemplate redisTemplate;

    private RedisTemplate<String, Integer> intRedisTemplate;

    @Resource
    private FwltjService fwltjService;

    private Logger logger = LoggerFactory.getLogger(MyJob.class);

    //PV,UV头缀
    String pVKeyPrefix = WebConstant.PV_KEY_PREFIX;
    String uVKeyPrefix = WebConstant.UV_KEY_PREFIX;

    /**
     * cron表达式
     * 每天 17:30:00 执行一次定时任务
     * @Scheduled(cron = "0 30 17 * * ?")
     * 每天 00:00:00执行一次定时任务
     */
    @Scheduled(cron = "0 0 0 * * ? ")
    public void cron() {
        logger.info(new Date() + " 进入定时任务");
        deleteKeyAndSaveDatabase();
        logger.info(new Date() + " 定时任务结束");
    }

    /**
     * 实例化到数据库中
     */
    public void deleteKeyAndSaveDatabase() {
        Fwltj fwltj = new Fwltj();
        logger.info(new Date() + " 实例化Redis缓存");
        RedisTemplate<String, Integer> intRedis = getIntRedisTemplate();

        //查询以此开头所有的key,工具替换keys
        Set<String> keysPv = scan(intRedis, pVKeyPrefix);
        Set<String> keysUv = scan(intRedis, uVKeyPrefix);

        //遍历所有的key,线程排队
        Vector<Thread> threadVector = new Vector<>();
        Thread childThread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (String pvRedisKey : keysPv) {

                    String visitIp = pvRedisKey.split("_")[1];
                    int pVNum = intRedis.opsForValue().get(pvRedisKey);

                    //uvKey为头缀+IP
                    String uvRedisKey = WebConstant.UV_KEY + visitIp;
                    Boolean pvKeyBoolean = intRedis.hasKey(uvRedisKey);
                    if (pvKeyBoolean) {
                        int uVNum = intRedis.opsForValue().get(uvRedisKey);
                        //将key,value实例化到数据库中
                        //访问时间,IP,PV,UV
                        fwltj.setTjrq(new Date());
                        fwltj.setIp(visitIp);
                        fwltj.setPv(pVNum + "");
                        fwltj.setUv(uVNum + "");
                        fwltjService.addF(fwltj);
                        logger.info("visitIp: " + visitIp + " , pVNum: " + pVNum + " , uVNum: " + uVNum);
                    }
                }
            }
        });
        threadVector.add(childThread);
        childThread.start();

        //线程排序
        for (Thread thread : threadVector) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //0点清除redis
        if (!keysPv.isEmpty() & !keysUv.isEmpty()) {
            //删除redis中所对应的值
            redisTemplate.delete(keysPv);
            redisTemplate.delete(keysUv);
            logger.info(new Date() + " 清除Redis缓存");
        }
    }

    /**
     * scan 实现批量查找key
     *
     * @param redisTemplate redisTemplate
     * @param pattern       表达式,如:abc*,找出所有以abc开始的键
     */
    public Set<String> scan(RedisTemplate<String, Integer> redisTemplate, String pattern) {
        return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            Set<String> keysTmp = new HashSet<>();
            try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
                    .match(pattern)
                    .count(10000).build())) {

                while (cursor.hasNext()) {
                    keysTmp.add(new String(cursor.next(), "Utf-8"));
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return keysTmp;
        });
    }

    /**
     * redis实例化
     *
     * @return
     */
    private RedisTemplate<String, Integer> getIntRedisTemplate() {
        if (intRedisTemplate == null) {
            intRedisTemplate = initTemplate();
        }
        return intRedisTemplate;
    }

    private RedisTemplate<String, Integer> initTemplate() {
        RedisTemplate<String, Integer> template = new RedisTemplate<String, Integer>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericToStringSerializer<Integer>(Integer.class));
        template.setExposeConnection(true);
        template.setConnectionFactory(redisTemplate.getConnectionFactory());
        template.afterPropertiesSet();
        return template;
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192858.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!