package com.xxx.fortuna.dao; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; /** * 更新数据 * * @author * */ public abstract class UpdateDBQueueBase<T> { private static Logger log = Logger.getLogger(UpdateDBQueueBase.class); private CopyOnWriteArrayList<LinkedBlockingQueue<T>> updateQueueList = new CopyOnWriteArrayList<LinkedBlockingQueue<T>>(); private int threadNum = 1; private AtomicInteger count = new AtomicInteger(0); private class updateDBThread implements Runnable { public LinkedBlockingQueue<T> queue; public updateDBThread(LinkedBlockingQueue<T> queue) { this.queue = queue; log.info("添加线程 updateDBThread!"); } @Override public void run() { while (true) { try { T update = queue.take(); update(update); } catch (Exception e) { log.error("updateDao erro:", e); } finally { if (!updateQueueList.contains(queue) && queue.size() == 0) { log.info("删除线程 updateDBThread!"); break; } } } } } /** * 按用户ID取模加入队列 * * @param splitId * @param update */ public void addUpdateQueue(long splitId, T update) { initThread(); int index = Math.abs((int) (splitId % 100 % updateQueueList.size())); updateQueueList.get(index).add(update); } /** * 加入当前队列最少等待的队列 * * @param update */ public void addUpdateQueueFromMin(T update) { initThread(); int index = 0; int min = 0; for (int i = 0; i < updateQueueList.size(); i++) { if (updateQueueList.get(i).size() < min) { min = updateQueueList.get(i).size(); index = i; } } updateQueueList.get(index).add(update); } /** * 轮询加入处理队列 * * @param update */ public void addUpdateQueue(T update){ initThread(); int index = count.addAndGet(1); if(index>=updateQueueList.size()){ index=0; count.set(0); } updateQueueList.get(index).add(update); } private void initThread() { int num = updateQueueList.size(); try { if (num < threadNum) { for (int i = num; i < threadNum; i++) { LinkedBlockingQueue<T> queue = new LinkedBlockingQueue<T>(); updateQueueList.add(queue); Thread thread = new Thread(new updateDBThread(queue)); thread.setName(getThreadName() + "-" + i); thread.start(); } } else if (num > threadNum) { List<LinkedBlockingQueue<T>> delList = new ArrayList<LinkedBlockingQueue<T>>(); for (int i = threadNum; i < num; i++) { delList.add(updateQueueList.get(i)); } for (LinkedBlockingQueue<T> delQueue : delList) { updateQueueList.remove(delQueue); } } } catch (Exception e) { log.error("UpdateDBQueueBase initThread ", e); } } /** * 线程名 * @return */ public abstract String getThreadName(); /** * 更新逻辑 * * @param update */ public abstract void update(T update) throws Exception; public int getThreadNum() { return threadNum; } public void setThreadNum(int threadNum) { this.threadNum = threadNum; } }
package com.xxx.fortuna.activity; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import com.happyelements.fortuna.dao.UpdateDBQueueBase; import com.happyelements.fortuna.mongo.MongoManger; public class BaiHeDao { private static BaiHeDao INSTANCE = null; public static BaiHeDao getInstance() { if (null == INSTANCE) { INSTANCE = new BaiHeDao(); } return INSTANCE; } private BaiHeDao() { userNumUpdate = new UpdateUserNum(); scoresUpdate = new UpdateScores(); } private UpdateUserNum userNumUpdate; public void addUserNumQueue(BaiHeTeamDO update) { userNumUpdate.addUpdateQueue(update); } private class UpdateUserNum extends UpdateDBQueueBase<BaiHeTeamDO> { public UpdateUserNum() { setThreadNum(1); } @Override public void update(BaiHeTeamDO update) throws Exception { Query query = Query.query(Criteria.where("id").is(update.getId())); Update numUpdate = new Update(); numUpdate.inc("userNum", update.getUserNum()); MongoManger.getInstance().update(query, numUpdate, BaiHeTeamDO.class); } @Override public String getThreadName() { return "BaiHeDao UpdateUserNum"; } } private UpdateScores scoresUpdate; public void addScoresQueue(BaiHeTeamDO update) { scoresUpdate.addUpdateQueue(update); } private class UpdateScores extends UpdateDBQueueBase<BaiHeTeamDO> { public UpdateScores() { setThreadNum(1); } @Override public void update(BaiHeTeamDO update) throws Exception { Query query = Query.query(Criteria.where("id").is(update.getId())); Update numUpdate = new Update(); numUpdate.inc("scores", update.getScores()); MongoManger.getInstance().update(query, numUpdate, BaiHeTeamDO.class); } @Override public String getThreadName() { return "BaiHeDao UpdateUserNum"; } } }
package com.xxx.fortuna.logic; import javapns.Push; import org.apache.log4j.Logger; import com.happyelements.fortuna.dao.UpdateDBQueueBase; import com.happyelements.fortuna.model.NotificationApalePO; /** * 给苹果推送消息的管理器 * * @author */ public class ApaleNotificationMgr { private static ApaleNotificationMgr INSTANCE = null; public static ApaleNotificationMgr getInstance() { if (null == INSTANCE) { INSTANCE = new ApaleNotificationMgr(); } return INSTANCE; } private ApaleNotificationMgr() { sendNotificationThread = new SendNotificationThread(); } private SendNotificationThread sendNotificationThread; private static Logger log = Logger.getLogger(ApaleNotificationMgr.class); public void addPushQueue(NotificationApalePO notification) { boolean openApaleNotification = Boolean .parseBoolean(GameConfigLogic.INSTANCE .getGameConfigValue("isApaleNotification")); if (null == notification || notification.getUid() <= 0 || !openApaleNotification) { return; } sendNotificationThread.addUpdateQueue(notification.getUid(), notification); } private class SendNotificationThread extends UpdateDBQueueBase<NotificationApalePO> { @Override public String getThreadName() { return "SendAppaleNotificationThread"; } @Override public void update(NotificationApalePO notification) throws Exception { if (!notification.isSend()) { log.info(notification.getUid() + " 因发送条件没达到无法发送 Apale Notification " + notification.getMsg()); return; } Push.alert(notification.getMsg(), notification.getpFileName(), GameConfigLogic.INSTANCE .getGameConfigValue("notification_password"), true, notification.getToken()); log.info(notification.getUid() + " 发送 Apale Notification 成功 " + notification.getMsg() + " " + notification.getpFileName() + " " + notification.getToken()); } } }