java模仿抢红包活动

抢红包活动所用到的一些多线程

public class RedPacketTask {
    private final static Logger logger = LoggerFactory.getLogger(RedPacketTask.class);

    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Autowired
    private ActivityRedService activityRedService;

    /** 存放所有启动定时任务对象,极其重要 **/
    private ConcurrentHashMap<String, ScheduledFuture<?>> scheduleMap = new ConcurrentHashMap<>();

    /** 扫描有效活动并开启 **/
    public void startActivity() {
        ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(new ActivityRunnable(), new CronTrigger("0/1 * * * * *"));
        scheduleMap.put("activity", future);
    }

    private class ActivityRunnable implements Runnable {
        @Override
        public void run() {
            //从redis中获取活动信息
            byte[]  activityRedByte = RedisService.getRedisService().getByte(RedisKeyConstants.ACTIVITY_RED_INFO);
            List<ActivityRed> activityRedList = FstSerializer.getInstance().deserialize(activityRedByte,ActivityRed.class);
            List<ActivityRed> activityRedResult = new ArrayList<>();
            activityRedList.stream().forEach(activityRed ->{
                boolean flag = accept(activityRed);
                if(flag){
                    activityRedResult.add(activityRed);
                }
            });
            activityRedList.removeAll(activityRedResult);
            byte[] activityRedBytes = FstSerializer.getInstance().serialize(activityRedList);
            RedisService.getRedisService().setByte(RedisKeyConstants.ACTIVITY_RED_INFO, activityRedBytes);
            RedisService.getRedisService().persist(RedisKeyConstants.ACTIVITY_RED_INFO);
        }

        private boolean accept(ActivityRed activityRed) {
            int taskInterval = activityRed.getTaskInterval();
            long period = taskInterval*60*1000;
            Date startTime = activityRed.getStartTime();
            Date endTime = activityRed.getEndTime();
            Date currentDate = new Date();
            //根据ID获取执行任务
            ScheduledFuture<?> future = scheduleMap.get(activityRed.getActivityRedId());
            //判断是否存在已开始的执行任务
            if (DateUtil.compareDate(startTime, currentDate)<=0 && future == null) {
                ScheduledFuture<?> addFuture = threadPoolTaskScheduler.scheduleAtFixedRate(
                        new RedPacketRunnable(activityRed), startTime, period);
                scheduleMap.put(activityRed.getActivityRedId(), addFuture);
            }

            if(DateUtil.compareDate(endTime, currentDate)<=0 ){
                //移除过期的活动
                if (future != null) {
                    future.cancel(true);
                }
                return true;
            }
            return false;
        }
    }

    private class RedPacketRunnable implements Runnable {

        private ActivityRed activityRed;

        RedPacketRunnable(ActivityRed activityRed){
            this.activityRed = activityRed;
        }

        @Override
        public void run() {
            //设置下一次抢红包时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE)+activityRed.getTaskInterval());
            logger.debug("将【{}】红包金额【{}】转到可用金额【{}】中并设置下一次抢红包时间【{}】",
                    activityRed.getActivityName(),
                    activityRed.getAmount(),
                    activityRed.getAvailableAmount(),
                    DateUtil.formatDate(calendar.getTime(),"yyyy-MM-dd HH:mm:ss"));

            activityRed.setAvailableAmount(activityRed.getAmount()+activityRed.getAvailableAmount());
            activityRed.setAmount(new Double(0));
            activityRedService.modActivityRed(activityRed);

            RedisService.getRedisService().set(activityRed.getActivityRedId()+":"+"nextTime",
                    DateUtil.formatDate(calendar.getTime(),"yyyy-MM-dd HH:mm:ss"));
            RedisService.getRedisService().expire(activityRed.getActivityRedId()+":"+"nextTime",activityRed.getTaskInterval()*60);
            //设置抢红时间
            RedisService.getRedisService().set(activityRed.getActivityRedId()+":"+"robTime", activityRed.getRobTimes().toString());
            RedisService.getRedisService().expire(activityRed.getActivityRedId()+":"+"robTime", activityRed.getRobTimes());
        }
    }
发布了237 篇原创文章 · 获赞 235 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/LRXmrlirixing/article/details/99415604
今日推荐