java多线程实现游戏组队demo

突发奇想的想写一个游戏组队的多线程实例,示例参考,多揪BUG 需求: 6人,10s 开局,overGame;

1 游戏线程

/**
     * 游戏线程
     *
     * @author DeanKano
     * @date 2018年3月17日
     */
    public static class GamePlayingThread extends Thread {

        // volatile并发可见性,保证同一时刻只有一个线程修改该变量
        private volatile boolean overGame;

        private long startTime = System.currentTimeMillis();

        private String name;

        private static final String ROOM_NAME_PREFIX = "R-";

        private GamePlayingThread(String teamName, int roomNum) {
            this.name = teamName + "(" + ROOM_NAME_PREFIX + roomNum + ")";
        }

        @Override
        public void run() {
            try {
                while (!overGame) {
                    synchronized (this) {
                        wait(2000);
                        log.info("{}:游戏 ing...", this.name);
                    }
                }
            } catch (InterruptedException ex) {
                log.error("{}:gameRunner interrupted !,exception:{}", this.name, ex);
            } finally {
                long recordTimes = getDiffSecondsFrom(this.startTime);
                log.info("{}::gameRunner over !,用时:{}(s)", this.name, recordTimes);
            }
        }

        public void overGame() {
            this.overGame = true;
            synchronized (this) {
                notifyAll();
            }
        }
    }

2 组队线程

/**
     * 组队线程
     *
     * @author DeanKano
     * @date 2018年3月17日
     */
    public static class GameTeamThread extends Thread {

        //倒计时(s)
        private static final long MAX_COUNT_DOWN_SECONDS = 10;
        // 是否可以组队
        private volatile boolean allowTeam = true;
        // 是否组队成功
        private volatile boolean teamResult = false;

        private Map<String, Boolean> playersMap;

        private long startTime = System.currentTimeMillis();

        private GamePlayingThread gameRunner;

        private String name;

        private static final String TEAM_NAME_PREFIX = "T-";

        private AtomicInteger roomNum = new AtomicInteger(10000);

        /**
         * @param players 玩家
         * @param teamNO 组队编号
         */
        private GameTeamThread(@NonNull List<String> players, int teamNO) {
            this.name = TEAM_NAME_PREFIX + teamNO;
            this.playersMap = players.stream().collect(Collectors.toMap(a -> a, b -> false));
            this.start();
        }

        /**
         * 玩家确认
         */
        private void readyOne(String playerName) {
            playersMap.computeIfPresent(playerName, (k, v) -> true);
        }

        private boolean isAllReady() {
            long countDownSeconds = getDiffSecondsFrom(this.startTime);
            // 未超时并且都确认啦
            return countDownSeconds <= MAX_COUNT_DOWN_SECONDS && !playersMap.values().contains(false);
        }

        @Override
        public void run() {
            try {
                while (allowTeam) {
                    sleep(2000);
                    if (teamResult) {
                        log.info("{}:组队成功,开始游戏", this.name);
                        this.gameRunner = new GamePlayingThread(this.name, roomNum.incrementAndGet());
                        gameRunner.start();
                        break;
                    }
                    long countDownSeconds = getDiffSecondsFrom(this.startTime);
                    if (countDownSeconds > MAX_COUNT_DOWN_SECONDS) {
                        this.allowTeam = false;
                        log.info("{}:组队失败,{}(s)超时,有玩家未确认", this.name, MAX_COUNT_DOWN_SECONDS);
                        break;
                    }
                    if (isAllReady()) {
                        this.teamResult = true;
                    }

                    log.info("{} 用时:{}s,->组队信息:{}", this.name, countDownSeconds, this.playersMap.toString());
                }
            } catch (InterruptedException ex) {
                log.error("{}:组队进程中断!,exception:{}", this.name, ex);
            }
        }


        public void stopTeam() {
            this.allowTeam = false;
            synchronized (this) {
                notifyAll();
            }
        }
    }

3 调用demo

 /**
     * 6人,10s 开局,overGame;
     * 示例:
     * round1 (有玩家未确认,10s后组队失败)
     * round2&round3  (玩家正常确认,正常在房间运行,游戏结束)
     */
    public static void main(String[] args) throws InterruptedException {

        AtomicInteger teamNO = new AtomicInteger(1000);
        List<String> players = Arrays.asList("玩家A", "玩家B", "玩家C", "玩家D", "玩家E", "玩家F");

        GameTeamThread round1 = new GameTeamThread(players, teamNO.incrementAndGet());
        round1.readyOne("玩家A");
        round1.readyOne("玩家C");
        round1.readyOne("玩家E");
        round1.readyOne("玩家F");
        Thread.sleep(4000);
        round1.readyOne("玩家D");

        GameTeamThread round2 = new GameTeamThread(players, teamNO.incrementAndGet());
        GameTeamThread round3 = new GameTeamThread(players, teamNO.incrementAndGet());
        // 玩家正常确认
        players.stream().forEach(round2::readyOne);
        players.stream().forEach(round3::readyOne);
        Thread.sleep(12000);
        round2.gameRunner.overGame();
        Thread.sleep(3000);
        round3.gameRunner.overGame();
    }

4 结果展示

14:23:59.918 [Thread-0] INFO cn.xiaolang.thread.GameDemo - T-1001 用时:2s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=false, 玩家A=true, 玩家D=false, 玩家C=true}
14:24:01.926 [Thread-0] INFO cn.xiaolang.thread.GameDemo - T-1001 用时:4s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=false, 玩家A=true, 玩家D=true, 玩家C=true}
14:24:03.914 [Thread-2] INFO cn.xiaolang.thread.GameDemo - T-1003 用时:2s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=true, 玩家A=true, 玩家D=true, 玩家C=true}
14:24:03.914 [Thread-1] INFO cn.xiaolang.thread.GameDemo - T-1002 用时:2s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=true, 玩家A=true, 玩家D=true, 玩家C=true}
14:24:03.926 [Thread-0] INFO cn.xiaolang.thread.GameDemo - T-1001 用时:6s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=false, 玩家A=true, 玩家D=true, 玩家C=true}
14:24:05.917 [Thread-2] INFO cn.xiaolang.thread.GameDemo - T-1003:组队成功,开始游戏
14:24:05.917 [Thread-1] INFO cn.xiaolang.thread.GameDemo - T-1002:组队成功,开始游戏
14:24:05.930 [Thread-0] INFO cn.xiaolang.thread.GameDemo - T-1001 用时:8s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=false, 玩家A=true, 玩家D=true, 玩家C=true}
14:24:07.922 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001):游戏 ing...
14:24:07.922 [Thread-4] INFO cn.xiaolang.thread.GameDemo - T-1002(R-10001):游戏 ing...
14:24:07.934 [Thread-0] INFO cn.xiaolang.thread.GameDemo - T-1001 用时:10s,->组队信息:{玩家F=true, 玩家E=true, 玩家B=false, 玩家A=true, 玩家D=true, 玩家C=true}
14:24:09.926 [Thread-4] INFO cn.xiaolang.thread.GameDemo - T-1002(R-10001):游戏 ing...
14:24:09.926 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001):游戏 ing...
14:24:09.938 [Thread-0] INFO cn.xiaolang.thread.GameDemo - T-1001:组队失败,有玩家未确认
14:24:11.927 [Thread-4] INFO cn.xiaolang.thread.GameDemo - T-1002(R-10001):游戏 ing...
14:24:11.928 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001):游戏 ing...
14:24:13.915 [Thread-4] INFO cn.xiaolang.thread.GameDemo - T-1002(R-10001):游戏 ing...
14:24:13.916 [Thread-4] INFO cn.xiaolang.thread.GameDemo - T-1002(R-10001)::gameRunner over !,用时:7(s)
14:24:13.928 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001):游戏 ing...
14:24:15.932 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001):游戏 ing...
14:24:16.918 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001):游戏 ing...
14:24:16.919 [Thread-3] INFO cn.xiaolang.thread.GameDemo - T-1003(R-10001)::gameRunner over !,用时:11(s)

公众号文章链接

https://mp.weixin.qq.com/s/r5LsCDp7IB7p9LlZcyYWpw

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值