Java tutorial
/** * @(#)CrontabService.java, 2016-3-4. * * Copyright 2016 Yodao, Inc. All rights reserved. * YODAO PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package outfox.dict.contest.service; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import lombok.Getter; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import outfox.dict.contest.dao.ContestDAO; import outfox.dict.contest.data.AreaEntity; import outfox.dict.contest.data.BaseEntity; import outfox.dict.contest.data.SingerEntity; import outfox.dict.contest.front.data.ContestConsts; import outfox.dict.contest.util.HttpToolKit; /** * * @author wangning * */ @Service public class CrontabService { private static final Logger LOG = Logger.getLogger(CrontabService.class); @Autowired private ContestDAO contestDAO; private volatile Map<String, String> singerInfoMap = new HashMap<String, String>(); private volatile Map<String, List<BaseEntity>> singersRankMap = new HashMap<String, List<BaseEntity>>(); private volatile Multimap<String, Integer> singersRandomMap = ArrayListMultimap.create(); @Getter private Map<String, Boolean> preparedBarrageMap = new HashMap<String, Boolean>(); public Map<String, String> getSingerInfoMap() { return singerInfoMap; } public Map<String, List<BaseEntity>> getSingersRankMap() { return singersRankMap; } public Multimap<String, Integer> getSingersRandomMap() { return singersRandomMap; } @PostConstruct public void init() { ScheduledExecutorService executor = Executors.newScheduledThreadPool(ContestConsts.CORE_POOL_SIZE); executor.scheduleAtFixedRate(new SingerInfoUpdate(), 0, ContestConsts.CRONTAB_TIME, TimeUnit.DAYS); // ???Zzzz // loadingPreparedBarrage(); } private class SingerInfoUpdate extends Thread { @Override public void run() { updateInfoInCache(); } } /* * ? */ public void updateInfoInCache() { LOG.info("updateInfo in cache Start..."); HttpResponse response = null; try { response = HttpToolKit.getInstance().doGet(ContestConsts.LIST_VOTE_INTERFACE); if (response != null) { HttpEntity entity = response.getEntity(); if (entity != null) { JSONObject jsonObj = JSON.parseObject(EntityUtils.toString(entity)); // ?json? if (jsonObj != null) { JSONArray dataArray = jsonObj.getJSONArray("data"); if (dataArray != null) { JSONObject dataObj = dataArray.getJSONObject(0); if (dataObj != null) { // ?? JSONObject voteinfo = dataObj.getJSONObject("voteinfo"); // ?? long startTime = 0, endTime = 0; if (voteinfo != null) { startTime = voteinfo.getLong("startTime"); endTime = voteinfo.getLong("endTime"); } // ??? JSONArray optionArray = dataObj.getJSONArray("options"); // options??? if (optionArray != null) { Object[] objArray = optionArray.toArray(); List<Map<String, String>> optionList = new ArrayList<Map<String, String>>(); Multimap<String, BaseEntity> rankMap = ArrayListMultimap.create(); for (Object obj : objArray) { JSONObject option = JSON.parseObject(obj.toString()); SingerEntity singer = new SingerEntity(); int optionId = option.getIntValue("id"); int voteNum = option.getIntValue("voteNum"); singer.setOptionId(optionId); singer.setPhotoUrl(option.getString("picture")); singer.setVoteNum(voteNum); singer.setStartTime(startTime); singer.setEndTime(endTime); String content = option.getString("content"); String areaName = null; int state = 0; if (StringUtils.isNotBlank(content)) { JSONObject contentObj = JSON.parseObject(content); singer.setId(contentObj.getIntValue("id")); singer.setName(contentObj.getString("name")); singer.setSchool(contentObj.getString("school")); areaName = contentObj.getString("areaName"); singer.setAreaName(areaName); singer.setAudioUrl(contentObj.getString("audioUrl")); singer.setMusicName(contentObj.getString("musicName")); state = contentObj.getIntValue("state"); singer.setState(state); } /** 1: ?mapkey?+optionid+statevalue? **/ singerInfoMap.put(ContestConsts.SINGER_INFO_PREFIX_KEY + optionId, JSON.toJSONString(singer)); /** 2: ???mapid??? **/ // 2.1: ?? rankMap.put(ContestConsts.RANK_PREFIX_KEY + areaName + ":" + state, new BaseEntity(optionId, voteNum)); // 2.2: ?? rankMap.put(ContestConsts.RANK_PREFIX_KEY + state, new BaseEntity(optionId, voteNum)); /** 3: ?mapid??? **/ // 3.1: ?idmap Map<String, String> map = new HashMap<String, String>(); map.put("areaName", areaName); map.put("optionId", String.valueOf(optionId)); map.put("state", String.valueOf(state)); optionList.add(map); } // 3.2: ?? Collections.shuffle(optionList); // 3.3: ??map Multimap<String, Integer> randomMap = ArrayListMultimap.create(); for (Map<String, String> map : optionList) { int optionId = Integer.parseInt(map.get("optionId")); int state = Integer.parseInt(map.get("state")); String areaName = map.get("areaName"); // 3.3.1 ? randomMap.put(ContestConsts.RANDOM_SHOWN_PREFIX_KEY + state, optionId); // 3.3.2 ?? randomMap.put( ContestConsts.RANDOM_SHOWN_PREFIX_KEY + areaName + ":" + state, optionId); } singersRandomMap = randomMap; /** 4???????? **/ // 4.1: ???? for (int state = 0; state <= 1; state++) { String key = ContestConsts.RANK_PREFIX_KEY + state; List<BaseEntity> globalRankList = (List<BaseEntity>) rankMap.get(key); Collections.sort(globalRankList, voteNumComparator); singersRankMap.put(key, globalRankList); } // 4.2: ??????100????? List<AreaEntity> areaList = contestDAO.listContestAreas(ContestConsts.PERIOD); if (areaList != null) { for (AreaEntity area : areaList) { // 4.2.1: ???? String key = ContestConsts.RANK_PREFIX_KEY + area.getName() + ":0"; List<BaseEntity> areaRankList = (List<BaseEntity>) rankMap.get(key); Collections.sort(areaRankList, voteNumComparator); singersRankMap.put(key, areaRankList); // 4.2.2: ?12???????12??1413?? if (areaRankList != null) { int rank = 0, lastVoteNum = -1, index = 1; for (BaseEntity ele : areaRankList) { String singerStr = singerInfoMap.get( ContestConsts.SINGER_INFO_PREFIX_KEY + ele.getId()); if (singerStr != null) { SingerEntity singer = JSON.parseObject(singerStr, SingerEntity.class); if (lastVoteNum != singer.getVoteNum()) { rank++; } singer.setRanking(rank); singer.setStartTime(area.getVoteStartTime()); singer.setEndTime(area.getVoteEndTime()); singerInfoMap.put( ContestConsts.SINGER_INFO_PREFIX_KEY + ele.getId(), JSON.toJSONString(singer)); index++; lastVoteNum = singer.getVoteNum(); // ?12???? if (index > ContestConsts.RANK_NUM) { break; } } } } } } } } } } } } } catch (Exception e) { LOG.error("CrontabService.singerInfoUpdate error...", e); } finally { HttpToolKit.closeQuiet(response); } LOG.info("updateInfo in cache End..."); } /** * ??? */ private static Comparator<BaseEntity> voteNumComparator = new Comparator<BaseEntity>() { @Override public int compare(BaseEntity o1, BaseEntity o2) { return o2.getVoteNum() - o1.getVoteNum(); } }; /** * Map */ public void loadingPreparedBarrage() { try { BufferedReader br = new BufferedReader(new FileReader(System.getProperty("barrageListPath"))); String line = null; while ((line = br.readLine()) != null) { if (StringUtils.isBlank(line) || line.startsWith("#")) { continue; } preparedBarrageMap.put(line, true); } } catch (FileNotFoundException e) { LOG.error("loadingPraparedBarrage file not found", e); } catch (Exception e) { LOG.error("loadingPraparedBarrage exception", e); } } }