我正在用Java制作一个实时多人游戏服务器。我将匹配的所有数据存储在带有"match“对象的HashMap中。每个匹配对象包含关于所有玩家的游戏和游戏状态的信息(在一场比赛中2-5之间的任何位置)。服务器将为每个用户与服务器的连接传递相同的匹配对象。
我有点担心的是让这条线安全。连接可以连接到服务器中的不同线程,所有这些线程都需要访问相同的匹配。
这方面的问题是,对象中将有许多变量/列表,所有这些变量/列表都需要同步。其中一些可能需要用于执行相互影响的计算,这意味着我需要嵌套的同步块,这是我不想要的。
对于match对象中的每个变量,同步块是我唯一的解决方案,还是可以执行其他操作?
我知道SQLite有一个内存模式,但我发现的问题是:
引用自他们的网站:
SQLite支持无限数量的同时读取器,但它只允许一个作者在任何时候。在许多情况下,这不是一个问题。作家排队。每个应用程序都能快速地运行数据库并继续工作,并且锁的持续时间不会超过几十毫秒。但是有些应用程序需要更多的并发性,而这些应用程序可能需要寻找不同的解决方案。
几十毫秒?那是很长的一段时间。这是足够快,还是在内存数据库中的另一个将适合于实时游戏?
发布于 2017-06-27 09:19:48
在这种情况下,您的体系结构是关闭的。您希望由多个线程同时修改和更新一组数据,这可能是可能的,但同时获得正确和快速的数据是非常困难的。
如果您按照以下方式更改体系结构,就会容易得多:
有一个线程具有对单个匹配对象的独占访问权限。一个线程可以处理多个匹配对象,但是单个匹配对象只能由单个线程处理/保护。现在,如果任何外部效果想要更改任何值,则需要发出“更改请求”,但不能立即自行更改。一旦实现了更改并更新了值,守护match对象的线程将向客户端发送更新。
因此,假设玩家得分,然后客户端线程调用一个函数。
void clientScoredGoal(Client client) {
actionQueue.put(new GoalScoredEvent(client));
}其中actionQueue是BlockingQueue。
处理匹配对象的线程正在通过actionQueue.take()侦听此队列,并在找到新操作后立即作出反应。然后,它将应用更改,必要时更新内部值,然后分发更新包(如果需要,向客户端分发“更改请求”)。
而且,在一般情况下,synchronized在Java中应该被认为是不好的实践。在某些情况下,它是处理同步的好方法,但在几乎99%的情况下,使用并发包的特性将是更好的解决方案。注意上面的示例代码中完全缺少synchronized,但是它完全是线程安全的。
发布于 2017-06-27 06:16:23
这个问题非常笼统。很难给出具体的建议。
我正在用Java制作一个实时多人游戏服务器。我将匹配的所有数据存储在带有"match“对象的HashMap中。
我有点担心的是让这条线安全。连接可以连接到服务器中的不同线程,所有这些线程都需要访问相同的匹配。
我需要嵌套的同步块,我不想这样做。
对于match对象中的每个变量,同步块是我唯一的解决方案,还是可以执行其他操作?我知道SQLite有一个内存模式
如果有多个线程访问的具有可变状态的对象,则需要确保它们的线程安全。没有其他方法(请注意,我没有说“同步块”是唯一的选择。实现线程安全有不同的方法)。使用内存中的数据库并不能解决线程安全问题。
使用内存中的数据库的优点是加快了对信息的访问(因为您不必使用存储在HDD中的信息访问常规数据库),但是现在应用程序需要更多的RAM。顺便说一句,与使用内存数据库相比,更快的是在程序中的对象中保存所需的所有信息(这与需要更多RAM的限制相同)。
https://stackoverflow.com/questions/44767564
复制相似问题