我在JavaFX中编写了一个格斗游戏,使用JDBC将信息更新到MySQL数据库中。如果不重复连续执行,从数据库服务器获取基本信息的大多数任务都能正常工作。问题出现在我需要程序不断更新对手的信息,比如游戏中的位置、等级、伤害等。我必须不断向服务器发送select命令,这会增加运行这些命令的线程使用的RAM。
void startUpdatingOpponentInfo() { Thread thread = new Thread(() -> { while (matchID != -1) { String query = String.format("select * from matchDetails where matchID = %d and userID = %d", matchID, opponentID); try { ResultSet resultSet = sqlConnection.getDataQuery(query); while (resultSet.next()) { double opponentX = resultSet.getDouble("xPos"); double opponentY = resultSet.getDouble("YPos"); if (opponentX != -1 && opponentY != -1) opponent.move(canvas, new Position(opponentX, opponentY)); } } catch (SQLException e) { e.printStackTrace(); } try { Thread.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); } public ResultSet getDataQuery(String query) { Statement statement; ResultSet resultSet = null; try { statement = connection.createStatement(); resultSet = statement.executeQuery(query); } catch (SQLException e) { System.out.println(query); e.printStackTrace(); } return resultSet; }
我尝试搜索了一些方法,找到了一个非常有用的方法。在每个select之后,我会让线程休眠一段时间,然后再进行select。这种方式显着提高了性能,RAM的消耗量保持稳定。然而,对于需要始终刷新的查询信息来说,这种方法并不适用,因为“select”线程的短暂休眠仍然会导致RAM消耗较高。是否有任何有用的方法解决这个问题,让我的游戏直接连接到数据库服务器,而不经过中间游戏服务器。
你应该首先尝试优化你的变量。
你的线程在查询时一直使用新的String,而实际上它只需要构建一次。同样,对于你的ResultSet,在每次进入新的循环时,你都会在RAM中使用一个新的位置来存储一个新的对象。
你可以通过在Java ID对象之外添加一个控制台输出来检查:
然后观察每次输出的结果是不是不同。
像这样:
然后我让你考虑改变你的查询,只选择xPos/yPos不等于"-1"的值,并且只获取真正的对手位置变化的结果,最后,也许不发送一个"new Position",而只发送两个变量opponentX和opponentY,这样可以避免将这个对象存储在RAM中。
不要忘记,Java只会在代码执行完成后清理你的RAM对象(简而言之),所以拥有一个永不结束的单一线程不会触发这种情况。