Question

I have two executorservices that runs every second. But one of them stops running when I have a line of code inserted in the run method. Here are my classes:

GameServer:

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;
    }
}

Player:

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;
    }
}

Main:

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);
    }
}

In the Player class, there is a commented line of code int randomGameServer =... The run method runs smoothly every second as expected. But if I uncomment it, The player run's method executes a few times only and stops. What I am trying to do is get the player to randomly select a game server to join. Does anyone know why it stops?

Outcome with commented line (Player runs continously):

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

Outcome with uncommented line (Player runs a few times):

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
Was it helpful?

Solution

You're never calling registerGameServer() so the HashMap is remaining empty and doing get() gives you a null result. Calling the getId() causes the NullPointerException.

Once you solve it have a look at the efficiency of your program. No need to create a new HashMap each time, get the same one and make it thread safe by using the concurrent version.

Also, for the Random, instead of creating a new one each time, use a ThreadLocalRandom.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top