2013-01-15 50 views
3

我正在編寫一個遊戲,其中玩家在JVM上編寫相互競爭的AI代理。現在的架構如下:確保線程在Java中獲得(大約)相等的CPU時間

  1. 核心服務器模塊,處理物理模擬,並從玩家的消息作爲輸入來改變世界。核心還根據各種規則(根據戰爭迷霧)從各個角色的角度確定世界的形象。
  2. 玩家模塊從核心接收世界的更新版本,處理它們,並根據該處理將消息流式傳輸到核心作爲輸入。

這個想法是,核心是與兩個播放器模塊一起編譯,然後運行模擬產生輸出流,可以回放以產生匹配的可視化。

我的問題是,如果每個玩家在單個Java線程上運行,是否可以確保兩個玩家線程獲得相同數量的資源(CPU時間,主要是我認爲的)?因爲我不控制每個人工智能所處理的處理的性質,所以有可能其中一個玩家的效率極低,但是其寫入方式使得其線程消耗瞭如此多的資源,其他玩家的AI資源匱乏並且可以競爭不公平。

我覺得如果沒有硬實時操作系統(JVM甚至沒有接近實際的操作系統),這是不可能的,但如果甚至有一種方法可以相當接近我想探索它。

+0

查看[this](http://www.java-samples.com/showtutorial.php?tutorialid=302)頁面。 –

回答

3

「播放器模塊從核心接收更新的世界版本,處理它們,並根據該處理將消息流式傳輸到作爲輸入的輸入」。這意味着播放器模塊內部有一個循環,它接收更新消息並將結果消息發送給內核。然後我會使用輕量級演員模型,每個演員都是演員,所有演員使用相同的ExecutorService。由於激活的actor通過相同的執行器任務隊列,他們對CPU的訪問大致相同。

+0

謝謝。我認爲這是我將要解決的解決方案 - 無論如何,我正在使用Scala編寫代碼,所以使用演員是不容易的。 –

+0

請注意,原生斯卡拉演員重量級(每個都有一個線程連接),所以使用Akka。 –

1

你的直覺是正確的,這在Java中是不可能的。即使你有一個實時操作系統,有人仍然可以編寫一個非常耗費資源的AI線程。

您可以採取幾種方法,至少可以幫助您。首先確保給兩個播放器模塊線程相同的優先級。如果您在擁有2個以上處理器的機器上運行,並且您將每個播放器模塊線程設置爲具有最高優先級,那麼理論上它們都應該在有需要時運行。但是如果沒有什麼能阻止玩家模塊自己產生新線程,那麼你不能保證玩家不會這麼做。

所以簡短的答案是否定的,你不能在java中做出這些保證。

根據你的模擬工作方式,也許你可以有一個「轉向」的概念。因此,模擬指示玩家1進行移動,然後玩家2進行移動,並且來回移動,因此他們每次只能進行一次「移動」。不知道這是否會在你的情況下工作。

+0

感謝您的回覆。我想到了轉彎 - 基本上更新了物理,從玩家A獲得輸入,從玩家B獲得輸入,再次更新物理 - 但在這種情況下,我想要一種方法來限制每個玩家得到的時間量提交它想要做的動作,這樣一個玩家就不會比另一個搗鼓的分析花費更多的時間量級(從而做出更好的動作)。 –

0

如果您有任何旋鈕轉動關於線程多少工作要做(或只設置它們的優先級),你可以建立另一個線程定期監視使用ThreadMXBean小號線程和使用ThreadInfo.getThreadCpuTime找到自己的CPU使用率。然後你可以比較每個玩家的CPU時間並作出相應的反應。
不知道這是否足夠及時和準確,但隨着時間的推移,您可以平衡CPU使用率。
但是,將數據包中的工作分開並使用前面建議的Executors應該是更好的方法,更像java。