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

确保线程在Java中获得(大约)相等的CPU时间,java,multithreading,concurrency,Java,Multithreading,Concurrency,我正在写一个游戏,玩家在JVM上编写相互竞争的AI代理。目前,该体系结构如下所示: 一个核心服务器模块,用于处理物理模拟,并将来自玩家的消息作为改变世界的输入。核心还根据不同的规则(想想战争之雾),从每个玩家的角度决定世界的样子 播放器模块从核心接收世界的更新版本,对其进行处理,并将消息作为基于该处理的输入流传送到核心 其思想是,核心与两个播放器模块一起编译,然后运行模拟,生成输出流,可以回放以生成比赛的可视化 我的问题是,如果每个播放器都在一个Java线程上运行,是否可以确保两个播放器线程获得

我正在写一个游戏,玩家在JVM上编写相互竞争的AI代理。目前,该体系结构如下所示:

  • 一个核心服务器模块,用于处理物理模拟,并将来自玩家的消息作为改变世界的输入。核心还根据不同的规则(想想战争之雾),从每个玩家的角度决定世界的样子
  • 播放器模块从核心接收世界的更新版本,对其进行处理,并将消息作为基于该处理的输入流传送到核心
  • 其思想是,核心与两个播放器模块一起编译,然后运行模拟,生成输出流,可以回放以生成比赛的可视化

    我的问题是,如果每个播放器都在一个Java线程上运行,是否可以确保两个播放器线程获得相等的资源量(我认为CPU时间是主要的)?因为我无法控制每个AI所做的处理的性质,有可能其中一个玩家的效率极低,但其线程消耗了大量资源,而另一个玩家的AI资源匮乏,无法公平竞争


    我觉得如果没有一个硬实时操作系统,这是不可能的,JVM甚至都不可能做到这一点,但是如果有一种方法可以达到相当接近的程度,我很想探索一下

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

    这里有几种方法至少可以帮助你。首先确保两个播放器模块线程具有相同的优先级。如果您在一台有2个以上处理器的机器上运行,并且您将每个播放器模块线程设置为具有最高优先级,那么从理论上讲,只要有事情要做,它们都应该运行。但是如果没有什么可以阻止玩家模块自己产生新的线程,那么你不能保证玩家不会这样做

    简而言之,答案是否定的,您不能用java做这些保证

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

    “播放器模块从core接收世界的更新版本,对其进行处理,并将消息流式传输到
    核心作为基于该处理的输入”。这意味着播放器模块内部有一个循环,用于接收更新消息并将结果消息发送到核心。然后我将使用轻量级的参与者模型,每个参与者都是参与者,所有参与者都使用相同的服务。由于激活的参与者通过相同的执行者任务队列,所以它们对CPU的访问权大致相同

    如果您有任何关于线程必须完成多少工作的旋钮(或只是设置它们的优先级),您可以设置另一个线程,使用
    ThreadMXBean
    s定期监视线程,并使用
    ThreadInfo.getThreadCpuTime
    查找它们的CPU使用情况。然后,您可以比较每个玩家的CPU时间,并做出相应的反应。
    不确定这对您来说是否足够及时和准确,但随着时间的推移,您可以平衡CPU使用。

    但是,将工作分成数据包并使用前面建议的执行器应该是更好的方法,而且更像java。

    签出页面。感谢您的回复。我考虑过轮换——基本上是更新物理,从玩家A获得输入,从玩家B获得输入,再次更新物理——但在这种情况下,我想要一种方法来限制每个玩家提交其想要的动作的时间,因此,一个玩家不能比另一个玩家花费更多的时间进行分析(从而做出更好的动作)。谢谢。我想这就是我将要使用的解决方案——反正我是用Scala编写代码的,所以使用actors是不需要动脑筋的。请注意,本机Scala actors是重量级的(每个都有一个线程连接),所以使用Akka。