【问题标题】:ScheduledExecutorService doesnt run after some timeScheduledExecutorService 一段时间后没有运行
【发布时间】:2012-11-11 03:43:34
【问题描述】:

我有两个每秒运行的执行器服务。但是当我在 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;
    }
}

服务器管理器:

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

【问题讨论】:

  • 你知道它停在哪里了吗?是否挂起,是否引发异常?在挂起之前你看到的最后一行是什么?
  • 它不会停止,Player run() 方法在一段时间后不会运行
  • 您能否尝试为每个玩家分配一个唯一编号并将其记录在 System.out 中,以便我们知道是否所有玩家都在运行,以及是否存在模式。
  • 好的,我在玩家运行方法中添加了一个 try/catch,并且出现了空指针异常。感谢@jbx 提醒我尝试捕获异常
  • 我想最好的尝试是在 Player.run() 的第一行放置一个断点,然后一步一步地查看发生了什么。

标签: java executorservice scheduledexecutorservice


【解决方案1】:

您永远不会调用registerGameServer(),因此HashMap 保持为空,并且执行get() 会给您一个空结果。调用getId() 会导致NullPointerException

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

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

【讨论】:

    猜你喜欢
    • 2016-08-25
    • 1970-01-01
    • 2017-10-17
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2021-04-29
    相关资源
    最近更新 更多