1

我正在开发一个基于文本的游戏,MUD。我已经准备好程序的基本功能,现在我想允许一次连接多个客户端。我计划使用线程来实现这一点。

在我的游戏中,我需要存储每个玩家的当前位置或健康点等信息。我可以将它保存在数据库中,但由于它会很快改变,有时每秒一次,使用数据库效率会低(我说的对吗?)。

我的问题是:线程可以表现为“会话”,即持有每个用户独有的一些数据吗?

如果是的话,你能指导我一些我可以用来帮助我理解它是如何工作的资源吗?

如果没有,你有什么建议?数据库是一个不错的选择还是您会推荐其他东西?

干杯,Eleeist

4

5 回答 5

5

是的,他们可以,但这是一种非常愚蠢的做事方式。一方面,它将您永久锁定在“每个客户端一个线程”模型中。另一方面,实现用户之间的交互变得困难(甚至不可能),我相信你的 MUD 有。

相反,拥有某种类型的集合来存储您的用户,以及每个用户的数据。将持久数据保存到数据库中,但您不需要在每次更改时更新临时数据。

处理此问题的一种方法是在每个用户中都有一个“更改”的布尔值。当您对用户进行重大更改时,请立即将其写入数据库。但如果这是例行的、非关键的更改,只需设置“已更改”标志。然后每隔一段时间就会出现一个线程并将更改的用户写入数据库(并清除“更改”标志)。

当然,使用适当的同步!

于 2012-01-25T20:27:33.467 回答
4

每个连接/用户会话的线程不会扩展。您只能有 N 个活动线程,其中 N 等于您的机器拥有的物理内核/处理器的数量。您还受到机器内存量的限制,您可以一次创建多少个线程,某些操作系统也只是设置了任意限制

线程在处理多个客户端时并没有什么神奇之处。它们只会使您的代码更加复杂且不确定性降低,因此当您开始寻找逻辑错误时,更难推断实际发生的情况。

每个连接/用户会话的线程将是一种反模式

线程应该是无状态的工作人员,可以将事情从并发队列中拉出来并处理数据。

查看并发映射以进行缓存(或使用一些适当的缓存解决方案)并处理它们,然后执行其他操作。查看java.util.concurrent正确实现某些东西所需的所有原始类。

于 2012-01-25T20:27:22.967 回答
1

我不用担心线程和线程安全,而是使用像HSQLDB这样的内存 SQL 数据库来存储会话信息。除了其他好处之外,如果您的 MUD 成为下一个愤怒的小鸟,您可以更轻松地扩大规模。

于 2012-01-25T20:45:36.387 回答
1

ThreadLocal 是您的朋友!:)

http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

ThreadLocal 在 Thread 本身上提供存储。因此,来自 2 个不同线程的完全相同的调用将返回/存储不同的数据。

最大的危险是线程之间存在泄漏。您必须绝对确定,如果其他用户使用了其他人使用的线程,您将重置/清除数据。

于 2012-01-25T20:21:34.627 回答
0

绝对可以将线程用作会话。但这有点离题了。

线程的要点是并发、异步执行的能力。很可能,您希望从 MUD 客户端接收到的事件以并行的、不受控制的顺序发生。

为了确保世界的一致性,我会使用内存数据库来存储游戏世界。我会序列化它的更新,或者至少对其进行一些更新。想象一下两个玩家平行击中一个生命值为 100 的怪物。每个人造成 100 点伤害。如果你不序列化更新,你最终可能会给两个玩家造成 100 点伤害。想象一下,两名玩家同时从怪物身上掠夺战利品。如果没有适当的序列化,他们最终可能会拥有自己的战利品副本。

另一方面,线程有利于与客户端进行异步通信。为此使用线程,除非其他东西(如 Web 服务器)已经为您执行此操作。

于 2012-01-25T20:37:02.720 回答