4

我已经编写了以下游戏服务器并希望提供组功能。组将允许将屏幕上“附近”的玩家组合在一起。在快速动作游戏中,由于玩家会不断地进出他们的区域,所以这个群体会快速变化。

由于每个玩家都需要收听组中其他玩家的事件,因此玩家将订阅该组。这让我想到了我的问题。在这种情况下可以使用什么适当的数据结构或 java 集合类来保存组上不断变化的事件侦听器集?在我看来,一个组的听众数量很少会超过 20,并且在大多数情况下应该少于这个数量。它是一个多线程环境。

我打算使用的是CopyOnWriteArrayList. 但是由于会有合理数量的更新(由于订阅的变化),这个类是否合适?还有什么其他类可以使用?如果您有任何使用数组等的自定义实现,请分享。

4

3 回答 3

2

除非您每秒有数百万次更改(这在您的场景中似乎不太可能),否则 aCopyOnWriteArrayList应该足以满足您的需要。如果我是你,我会使用它。

如果您注意到性能问题并且您已经分析了您的应用程序并且您已经确定这CopyOnWriteArrayList是瓶颈,那么您可以找到更好的结构。但我怀疑会是这样。

于 2012-05-09T09:24:29.853 回答
1

玩家是否有整数 ID?如果是这样,那么我有一个轻量级、不可变的基于数组的集合类,它可能对您有意义:

这是为游戏引擎中的类似情况编写的。

但是,我还可以考虑另一种方法:如果您要根据附近自动更新组,那么您可能需要考虑根本不跟踪组。相反,可以考虑使用一种空间数据结构,让您可以在事件发生时快速搜索附近的玩家,并将事件直接发送给附近的玩家。

通常,您可以使用 2D 或 3D 网格或八叉树,将最小划分大小设置为等于您的组的最大范围。然后附近搜索将只需要检查 9 个(2D 案例)或 27 个(3D 案例)位置即可找到所有附近的玩家。我认为在需要时进行此搜索将比一直维护组和侦听器列表的开销更快、更简单......

于 2012-05-09T09:36:10.000 回答
1

根据我收集到的信息,您可以在 和 之间进行CopyOnWriteArrayList选择ConcurrentHashMap

CopyOnWriteArrayList:

  1. 添加/删除操作的计算成本与列表的大小成线性关系。在一次迭代中可能会发生多次(组通知)。
  2. 具有恒定读取时间的更简单的数据结构。

并发哈希映射:

  1. 添加/删除操作是一个恒定时间操作。订阅者的添加或删除不会影响已经在进行的迭代,并且可以最大限度地减少阻塞。
  2. 更大的数据结构,需要稍长的读取时间。

在效率方面创建自定义解决方案是可能的,但在线程安全方面可能不那么安全。我倾向于,ConcurrentHashMap但获胜者可能在很大程度上取决于你的游戏结果。

于 2012-05-09T06:30:44.930 回答