首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >内存数据存储中的Java线程安全

内存数据存储中的Java线程安全
EN

Stack Overflow用户
提问于 2017-06-26 19:47:19
回答 2查看 1.4K关注 0票数 0

我正在用Java制作一个实时多人游戏服务器。我将匹配的所有数据存储在带有"match“对象的HashMap中。每个匹配对象包含关于所有玩家的游戏和游戏状态的信息(在一场比赛中2-5之间的任何位置)。服务器将为每个用户与服务器的连接传递相同的匹配对象。

我有点担心的是让这条线安全。连接可以连接到服务器中的不同线程,所有这些线程都需要访问相同的匹配。

这方面的问题是,对象中将有许多变量/列表,所有这些变量/列表都需要同步。其中一些可能需要用于执行相互影响的计算,这意味着我需要嵌套的同步块,这是我不想要的。

对于match对象中的每个变量,同步块是我唯一的解决方案,还是可以执行其他操作?

我知道SQLite有一个内存模式,但我发现的问题是:

引用自他们的网站:

SQLite支持无限数量的同时读取器,但它只允许一个作者在任何时候。在许多情况下,这不是一个问题。作家排队。每个应用程序都能快速地运行数据库并继续工作,并且锁的持续时间不会超过几十毫秒。但是有些应用程序需要更多的并发性,而这些应用程序可能需要寻找不同的解决方案。

几十毫秒?那是很长的一段时间。这是足够快,还是在内存数据库中的另一个将适合于实时游戏?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-27 09:19:48

在这种情况下,您的体系结构是关闭的。您希望由多个线程同时修改和更新一组数据,这可能是可能的,但同时获得正确和快速的数据是非常困难的。

如果您按照以下方式更改体系结构,就会容易得多:

有一个线程具有对单个匹配对象的独占访问权限。一个线程可以处理多个匹配对象,但是单个匹配对象只能由单个线程处理/保护。现在,如果任何外部效果想要更改任何值,则需要发出“更改请求”,但不能立即自行更改。一旦实现了更改并更新了值,守护match对象的线程将向客户端发送更新。

因此,假设玩家得分,然后客户端线程调用一个函数。

代码语言:javascript
运行
复制
void clientScoredGoal(Client client) {
  actionQueue.put(new GoalScoredEvent(client));
}

其中actionQueue是BlockingQueue。

处理匹配对象的线程正在通过actionQueue.take()侦听此队列,并在找到新操作后立即作出反应。然后,它将应用更改,必要时更新内部值,然后分发更新包(如果需要,向客户端分发“更改请求”)。

而且,在一般情况下,synchronized在Java中应该被认为是不好的实践。在某些情况下,它是处理同步的好方法,但在几乎99%的情况下,使用并发包的特性将是更好的解决方案。注意上面的示例代码中完全缺少synchronized,但是它完全是线程安全的。

票数 1
EN

Stack Overflow用户

发布于 2017-06-27 06:16:23

这个问题非常笼统。很难给出具体的建议。

我正在用Java制作一个实时多人游戏服务器。我将匹配的所有数据存储在带有"match“对象的HashMap中。

  • 如果要将“匹配”对象存储在map中,然后有多个线程请求/添加/删除映射中的对象,则必须使用"ConcurrentHashMap“。

我有点担心的是让这条线安全。连接可以连接到服务器中的不同线程,所有这些线程都需要访问相同的匹配。

  • 拥有多线程的最安全和最简单的方法是使每个“匹配”成为一个不变的对象,然后就不需要同步了。
  • 如果“匹配”信息是可变的,并且被多个线程同时访问,那么您将不得不进行同步。但在这种情况下,“可变状态”包含在“匹配”中,因此只有类“匹配”才需要使用同步。

我需要嵌套的同步块,我不想这样做。

  • 我从未见过需要嵌套同步块。也许您应该重构您的解决方案,然后再尝试使其线程安全。

对于match对象中的每个变量,同步块是我唯一的解决方案,还是可以执行其他操作?我知道SQLite有一个内存模式

如果有多个线程访问的具有可变状态的对象,则需要确保它们的线程安全。没有其他方法(请注意,我没有说“同步块”是唯一的选择。实现线程安全有不同的方法)。使用内存中的数据库并不能解决线程安全问题。

使用内存中的数据库的优点是加快了对信息的访问(因为您不必使用存储在HDD中的信息访问常规数据库),但是现在应用程序需要更多的RAM。顺便说一句,与使用内存数据库相比,更快的是在程序中的对象中保存所需的所有信息(这与需要更多RAM的限制相同)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44767564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档