使用优先队列实现游戏公告模块(Java)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hspingcc/article/details/51837832

一.问题描述

**实现公告消息分优先级,优先级高的公告,优先推送,同一优先在其后面加入.有点像是队列里面的分组还是队列的数据结构.

思路首先使用优先级做队列,然后根据时间戳做队列.然后定期推送.如果优先级高者加入,立刻推送,并将未播放完的公告加入队列.**

二.相关的类和方法的实现

Notice类:公告的消息体

/**
 * 公告信息体
 * 
 * @author insping
 *
 */
public class Notice {
    int priorLevel; // 优先级
    long time; // 消息的时间戳
    Object obj; // 公告体,可以是任意对象

    public Notice() {

    }

    public Notice(int priorLevel, long time, Object obj) {
        this.priorLevel = priorLevel;
        this.time = time;
        this.obj = obj;
    }

    public int getPriorLevel() {
        return priorLevel;
    }

    public void setPriorLevel(int priorLevel) {
        this.priorLevel = priorLevel;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

}

NoticeManager类:公告的管理类

import java.util.Comparator;
import java.util.PriorityQueue;

public class NoticeManager {
    private static NoticeManager instance = new NoticeManager();

    public static NoticeManager getInstance() {
        return instance;
    }

    public PriorityQueue<Notice> worldNotices = new PriorityQueue<Notice>(11, new Comparator<Notice>() {
        @Override
        public int compare(Notice o1, Notice o2) {
            int numbera = o1.getPriorLevel();
            int numberb = o2.getPriorLevel();
            long timea = o1.getTime();
            long timeb = o2.getTime();
            return numberb == numbera ? (timea == timeb ? 0 : (timea < timeb ? -1 : 1)) : (numbera > numberb ? -1 : 1);
        }
    });// 世界公告
    long noticeStart = System.currentTimeMillis(); // 公告消息的时间
    Notice priorNotice = new Notice();// 用作记录上次所发送的公告

    /**
     * 发送一条公告消息(优先展示)
     * 
     * @param msg
     */
    public void addNotice(Notice noticeMsg) {
        synchronized (worldNotices) {
            worldNotices.add(noticeMsg);
            if (noticeMsg.getPriorLevel() > priorNotice.getPriorLevel() && priorNotice.getTime() != 0) {
                worldNotices.add(priorNotice);
                noticeStart = 0; // 让头数据立刻下发
            }
        }
    }

    /**
     * 推送一条公告消息
     */
    public boolean sendHeadWorldNotice() {
        synchronized (worldNotices) {
            Notice noticeMsg = worldNotices.poll();
            if (noticeMsg == null) {
                return false;
            }
            priorNotice = noticeMsg;
            // 想所有在线的玩家推送notice
            // sendToAllRole(noticeMsg);
            System.out.println(noticeMsg.getObj()); //做测试显示.
            return true;
        }
    }

    /**
     * 定期向所有在线的用户 发送公告消息
     */
    public boolean sendHeadWorldNoticeToAllOnlineRoles() {
        // 刷新公告信息
        synchronized (worldNotices) {
            if (worldNotices.size() > 0 && System.currentTimeMillis() - noticeStart >= 20 * 1000) {
                if (!sendHeadWorldNotice()) {
                    return false;
                }
                noticeStart = System.currentTimeMillis();
                return true;
            }
            return false;
        }
    }
}

NoticeThread类:公告线程


public class NoticeThread extends Thread implements Instance {
    @Override
    public void run() {
        while (1 != 0) // !ServiceApp.FREEZE 可以判断服务的状态
            try {
                noticeMgr.sendHeadWorldNoticeToAllOnlineRoles();
            } catch (Exception e) {
                System.out.println(e);
            }
    }
}

Instance接口


public interface Instance {
    public static final NoticeManager noticeMgr = NoticeManager.getInstance();
}

测试程序:

    public static void main(String args[]) throws InterruptedException {
        NoticeThread noticeThread = new NoticeThread();
        noticeThread.start();
        Notice noticeMsg = new Notice(2,System.currentTimeMillis(), (Object) 1);
        noticeMgr.addNotice(noticeMsg);
        noticeMgr.sendHeadWorldNotice();
        Thread.sleep(1000);
        Notice noticeMsg1 = new Notice(1, System.currentTimeMillis(), (Object) 2);
        noticeMgr.addNotice(noticeMsg1);
        Thread.sleep(1000);
        Notice noticeMsg2 = new Notice(2, System.currentTimeMillis(), (Object) 4);
        noticeMgr.addNotice(noticeMsg2);
        Thread.sleep(1000);
        Notice noticeMsg3 = new Notice(3, System.currentTimeMillis(), (Object) 3);
        noticeMgr.addNotice(noticeMsg3);
        }

结果:
1
3
1
4
2

展开阅读全文

没有更多推荐了,返回首页