我正在开发基于文本的游戏MUD。我已准备好程序的基本功能,现在我想允许一次连接多个客户端。我计划使用线程来实现这一目标。
在我的游戏中,我需要存储每个玩家的当前位置或健康点等信息。我可以把它保存在数据库中,但是因为它会很快变化,有时每秒都会变化,使用数据库效率很低(我是对的吗?)。
我的问题是:线程可以表现为“会话”,即保存每个用户独有的一些数据吗?
如果是的话,你能指导我一些我可以用来帮助我了解它是如何工作的资源吗?
如果不是,你有什么建议?数据库是一个不错的选择还是你会推荐别的东西?
干杯, Eleeist
答案 0 :(得分:5)
是的,他们可以,但这是一种令人难以置信的愚蠢做事方式。首先,它会永久锁定您的“每个客户端一个线程”模型。另一方面,它使得用户之间的交互变得困难(甚至可能是不可能的),我确信你的MUD有。
相反,有一个存储用户的某种集合,每个用户都有数据。将持久数据保存到数据库,但不需要在每次更改时更新临时数据。
处理此问题的一种方法是在每个用户中使用“已更改”布尔值。对用户进行重要更改时,请立即将其写入数据库。但如果这是一个例行的非关键变化,只需设置“已更改”标志即可。然后每隔一段时间就有一个线程,并将更改的用户写入数据库(并清除“已更改”标志)。
当然,请使用适当的同步!
答案 1 :(得分:4)
每个连接/用户会话的线程不会扩展。您只能激活N个线程,其中N等于您的机器具有的物理核心/处理器的数量。您还受限于计算机中可以创建时间的线程数some operating systems just put arbitrary limits as well。
处理多个客户端时,Threads没有什么神奇之处。它们只会使您的代码更复杂,更不确定,因此当您开始寻找逻辑错误时,更难以推断实际发生的事情。
每个连接/用户会话的线程将是反模式!
线程应该是无状态工作者,它们可以解决并发队列并处理数据的问题。
查看并发映射以进行缓存(或使用一些适当的缓存解决方案)并处理它们,然后执行其他操作。有关正确实现内容所需的所有基本类,请参阅java.util.concurrent
。
答案 2 :(得分:1)
ThreadLocal是你的朋友! :)
http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
ThreadLocal在Thread本身提供存储。因此,来自2个不同线程的完全相同的调用将返回/存储不同的数据。
最大的危险是线程之间发生泄漏。您必须绝对确定如果其他用户使用了其他人使用的线程,您将重置/清除数据。
答案 3 :(得分:1)
我不会担心线程和线程安全,而是使用像HSQLDB这样的内存SQL数据库来存储会话信息。除了其他好处之外,如果你的MUD成为下一个愤怒的小鸟,你可以更轻松地扩展它。
答案 4 :(得分:0)
绝对可以将线程用作会话。但它有点偏离标准。
线程的要点是并发,异步执行的能力。最有可能的是,不希望从MUD客户端收到的事件以并行,不受控制的顺序发生。
为了确保世界的一致性,我会使用内存数据库来存储游戏世界。我会对它进行序列化更新,或者至少对它进行一些更新。想象一下,两名玩家同时击中一个拥有HP 100的怪物。每个造成100点伤害。如果您没有序列化更新,最终可能会对两位玩家造成100点伤害。想象一下两名玩家同时从怪物身上夺取战利品。如果没有适当的序列化,他们最终可能会拥有自己的战利品副本。
另一方面,线程适用于与客户端的异步通信。使用线程,除非其他东西(如Web服务器)已经为你做了。