确保线程在Java中获得(大致)相等的CPU时间

时间:2013-01-15 04:28:52

标签: java multithreading concurrency

我正在编写一个游戏,其中玩家在JVM上编写彼此竞争的AI代理。现在架构看起来像这样:

  1. 核心服务器模块,用于处理物理模拟,并将来自玩家的消息作为输入来改变世界。根据各种规则(认为战争迷雾),核心也从每个球员的角度确定世界的样子。
  2. 播放器模块从核心接收更新版本的世界,处理它们,并根据该处理将消息作为输入流式传输到核心。
  3. 这个想法是核心与两个播放器模块一起编译,然后运行模拟产生一个输出流,可以播放该输出流以生成匹配的可视化。

    我的问题是,如果每个玩家都在一个Java线程上运行,是否有可能确保两个玩家线程获得相同数量的资源(主要是CPU时间)?因为我不控制每个AI正在进行的处理的性质,所以其中一个玩家的效率可能非常低效,但其编写方式使得其线程消耗了如此多的资源,而其他玩家的AI资源匮乏且可以公平竞争。

    我觉得如果没有硬实时操作系统这是不可能的,JVM甚至不是很接近,但如果有一种方法可以合理地接近,我很乐意探索它。

3 个答案:

答案 0 :(得分:3)

“播放器模块从核心接收世界的更新版本,处理它们,并将消息流传输到 核心作为基于该处理的输入“。这意味着播放器模块内部有一个循环,它接收更新消息并将结果消息发送到核心。然后我将使用轻量级演员模型,每个玩家都是演员,所有演员使用相同的ExecutorService。由于激活的actor经历了相同的执行任务队列,因此它们对CPU的访问权限大致相同。

答案 1 :(得分:1)

你的直觉是正确的,这在Java中是不可能的。即使你有一个实时操作系统,有人仍然可以编写一个资源密集型的AI线程。

您可以采取几种方法来至少提供帮助。首先要确保给两个播放器模块线程相同的优先级。如果您在具有2个以上处理器的计算机上运行,​​并且将每个播放器模块线程设置为具有最高优先级,那么理论上它们应该在有任何操作时运行。但如果没有什么可以阻止玩家模块自己产生新线程,那么你无法保证玩家不会这样做。

如此简短的回答是否定的,你不能在java中做出这些保证。

根据您的模拟工作方式,也许您可​​以拥有“转弯”的概念。因此,模拟指示玩家1进行移动,然后玩家2进行移动,来回移动,因此他们每次只能进行一次“移动”。不确定这是否适用于您的情况。

答案 2 :(得分:0)

如果你有关于线程必须做多少工作(或者只是设置它们的优先级)的任何旋钮,你可以设置另一个线程,使用ThreadMXBean周期性地监视线程并找到它们的CPU使用率ThreadInfo.getThreadCpuTime。然后,您可以比较每个玩家的CPU时间并做出相应的反应 不确定这对您来说是否及时准确,但随着时间的推移,您可以平衡CPU使用率 但是,在数据包中拆分工作并使用之前建议的执行程序应该是更好的方式,而且更像java。