一些背景
所以我目前正在开发一个游戏项目,我加入了课外活动,并且在过去一年左右的时间里确实意识到了线程问题和并发性的后果。
我们当时遇到的一个重大问题是关闭服务器并保存:断开所有客户端并保存它们被证明是一个问题,因为我们会遇到并发问题。虽然我们已经解决了这个问题,但我又遇到了另一种可能的并发问题。
问题
我目前正在参与游戏的万圣节活动,并且应该每隔一段时间举行一次全球活动,其中所有玩家在该特定时间在线直接收到礼物他们的库存。
通常情况下,我会考虑在线抓住当前的玩家并运行所有玩家并给他们一个项目,但我相信会有这样的后果。
可能出现的问题
我想知道是否有更好的方法来解决这个问题。也许我可以将礼物分发到一个中心位置,玩家可以在这里稍后捡起它,从而避免可能成百上千的玩家的巨大循环。 我们确实遇到了大约200名在线玩家的并发问题。
MVE
由于我正在讨论迭代大型数据集的概念以及与之相关的并发问题,因此我不太确定要在MVE中提供什么,我不认为非常容易复制(?)。如果我错了,我会尽力提供与代码相关的内容。
答案 0 :(得分:1)
理想情况下,没有内部技术限制要求用户登录才能收到礼物。但听起来你确实遇到过这样的问题。
如果您收集的用户对象是为了在用户退出时赠送礼物成为垃圾收集的候选者,那么您的送礼收藏品应该weak references保留给这些用户对象。弱引用允许垃圾收集继续进行,而常规强引用将取消引用对象成为垃圾收集候选者的资格。见WeakReference
class。
创建一个空的List
或Set
。
List< WeakReference< User > > u = new ArrayList< User >() ;
迭代您当前登录的用户。将每个用户对象包裹在WeakReference
中。对于送礼,迭代第二个列表/集合,检查每个WeakReference
以查看其指示对象是否仍然可用,如果是,则给予礼物。如果没有,请转到下一个。
WeakReference< User > weakUser = new WeakReference<>( user );
u.add( weakUser ) ;
收集后,将该列表包装为不可变的习惯。
List< WeakReference< User > > users = Collections.unmodifiableList( u );
实际上,每当您要求当前登录的用户时,您的用户管理模块应该发出这种不可修改的WeakReference
对象列表/集。即使在组装初始列表/集合时,这些用户也可能随时注销。并始终发出一个新实例化的新集合,一个维护在您的用户管理模块内部的集合的副本。因此,如果构建WeakReference
的新列表/集合,您的送礼代码不应该执行此工作;应该已经代表它完成了这项工作。
顺便说一下......如果你有多个核心在生产中,并且想要得到想象,你可以将你的WeakReference
对象集合提供给新的Java 8 Streams功能,自动拆分为并行处理你的送礼。
提示:您似乎太担心性能,并不担心并发性。
提示:通过Java Concurrency In Practice,Oracle的 Java语言架构师阅读并重读本书Brian Goetz。我第五次重读。