ScheduledExecutorService在一段时间后不会运行

时间:2012-11-11 03:43:34

标签: java executorservice scheduledexecutorservice

我有两个每秒运行的执行器服务。但是当我在run方法中插入一行代码时,其中一个停止运行。这是我的课程:

游戏服务器:

public class GameServer implements Runnable {

    private ServerManager server;
    private int id;

    public GameServer(ServerManager sm) {
        server = sm;
        id = server.idCreator();
        server.registerGameServer(this);
    }

    @Override
    public void run() {
        System.out.println("Game server is collecting data every second");
    }

    public int getId() {
        return id;
    }
}

ServerManager的:

import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class ServerManager {

    private final AtomicInteger count = new AtomicInteger(0);
    private HashMap<Integer, GameServer> listofGameServers = new HashMap<>();

    public ServerManager() {
    }

    public void registerGameServer(GameServer gs) {
        listofGameServers.put(gs.getId(), gs);
    }

    public HashMap<Integer, GameServer> getGameServers() {
        return new HashMap<>(listofGameServers);
    }

    public int idCreator() {
        synchronized (count) {
            return count.incrementAndGet();
        }
    }

    public int generateRandomNumber(int start, int end) {
        Random rand = new Random();
        int number = start + rand.nextInt(end - start + 1);
        return number;
    }
}

播放器:

import java.util.HashMap;

public class Player implements Runnable {

    private int id;
    private ServerManager server;

    public Player(ServerManager sm) {
        this.server = sm;
        this.id = server.idCreator();
    }

    @Override
    public void run() {
        System.out.println("Player running every second");

        HashMap<Integer, GameServer> listOfGameServers = server.getGameServers();

        //int randomGameServer = listOfGameServers.get(server.generateRandomNumber(0, listOfGameServers.size()-1)).getId();
        int a = server.generateRandomNumber(0, listOfGameServers.size() - 1);
        System.out.println("Player selected a server: " + a);
    }

    public int getId() {
        return id;
    }
}

主:

import java.util.concurrent.*;

public class TestDriver {

    public static void main(String[] args) {
        ServerManager server = new ServerManager();

        ScheduledExecutorService game = Executors.newScheduledThreadPool(3);
        for (int j = 0; j < 3; j++) {
            game.scheduleAtFixedRate(new GameServer(server), 0, 1, TimeUnit.SECONDS);
        }

        ScheduledExecutorService prodExec = Executors.newScheduledThreadPool(3);
        prodExec.scheduleAtFixedRate(new Player(server), 0, 1, TimeUnit.SECONDS);
    }
}

Player类中,有一行注释代码int randomGameServer =... run方法按预期平滑运行。但如果我取消注释,播放器运行的方法只执行几次并停止。我想要做的是让玩家随机选择一个游戏服务器加入。有谁知道为什么会停止?

评论线的结果(播放器不断运行):

Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 0
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 2
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 2
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 1
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 0
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 0

未注释的结果(播放器运行几次):

Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Player selected a server: 1
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Player running every second
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second
Game server is collecting data every second

1 个答案:

答案 0 :(得分:1)

您永远不会致电registerGameServer(),因此HashMap仍为空,而get()会为您提供空结果。致电getId()会导致NullPointerException

一旦你解决它,看看你的程序的效率。无需每次都创建一个新的HashMap,使用并发版本获得相同的一个并使其线程安全。

此外,对于Random,不是每次都创建一个新的,而是使用ThreadLocalRandom