我正在编写一个游戏,其中玩家在JVM上编写彼此竞争的AI代理。现在架构看起来像这样:
这个想法是核心与两个播放器模块一起编译,然后运行模拟产生一个输出流,可以播放该输出流以生成匹配的可视化。
我的问题是,如果每个玩家都在一个Java线程上运行,是否有可能确保两个玩家线程获得相同数量的资源(主要是CPU时间)?因为我不控制每个AI正在进行的处理的性质,所以其中一个玩家的效率可能非常低效,但其编写方式使得其线程消耗了如此多的资源,而其他玩家的AI资源匮乏且可以公平竞争。
我觉得如果没有硬实时操作系统这是不可能的,JVM甚至不是很接近,但如果有一种方法可以合理地接近,我很乐意探索它。
答案 0 :(得分:3)
“播放器模块从核心接收世界的更新版本,处理它们,并将消息流传输到 核心作为基于该处理的输入“。这意味着播放器模块内部有一个循环,它接收更新消息并将结果消息发送到核心。然后我将使用轻量级演员模型,每个玩家都是演员,所有演员使用相同的ExecutorService。由于激活的actor经历了相同的执行任务队列,因此它们对CPU的访问权限大致相同。
答案 1 :(得分:1)
你的直觉是正确的,这在Java中是不可能的。即使你有一个实时操作系统,有人仍然可以编写一个资源密集型的AI线程。
您可以采取几种方法来至少提供帮助。首先要确保给两个播放器模块线程相同的优先级。如果您在具有2个以上处理器的计算机上运行,并且将每个播放器模块线程设置为具有最高优先级,那么理论上它们应该在有任何操作时运行。但如果没有什么可以阻止玩家模块自己产生新线程,那么你无法保证玩家不会这样做。
如此简短的回答是否定的,你不能在java中做出这些保证。
根据您的模拟工作方式,也许您可以拥有“转弯”的概念。因此,模拟指示玩家1进行移动,然后玩家2进行移动,来回移动,因此他们每次只能进行一次“移动”。不确定这是否适用于您的情况。
答案 2 :(得分:0)
如果你有关于线程必须做多少工作(或者只是设置它们的优先级)的任何旋钮,你可以设置另一个线程,使用ThreadMXBean
周期性地监视线程并找到它们的CPU使用率ThreadInfo.getThreadCpuTime
。然后,您可以比较每个玩家的CPU时间并做出相应的反应
不确定这对您来说是否及时准确,但随着时间的推移,您可以平衡CPU使用率
但是,在数据包中拆分工作并使用之前建议的执行程序应该是更好的方式,而且更像java。