2013-05-19 130 views
0

我有一個應該同時運行多個線程的程序。Java線程切換

這是一款紙牌遊戲Uno的模擬,你應該爲每個玩家設置一個線程。

現在這裏有一個問題:每當一名牌手拿到一張卡牌時,手牌上的卡牌數量和顏色都是相同的,但這不是輪到這個牌手,他可以「切斷」線路並放下卡牌。切線的球員旁邊的球員繼續。

我有一類球員:

class Player implements Runnable { 

    public boolean isHisTurn = false; 

    public Thread makeMove(final Card topCard, final boolean isHisTurn) { 
     Thread thread = new Thread(this); 
     thread.start(); 
     return thread; 
    } 
} 

thread.start(),然後開始運行方法,在那裏我有我的邏輯和決策。在運行()開始時,線程會隨機休眠300-700毫秒,以便在此時間框架內實現切割線。

我的問題是,我是否應該將線程存儲在某個地方,如果是,在哪裏,以及如何在不同的玩家輪流之間切換線程?我知道它與布爾isHisTurn有關,我只是不知道如何使用它。

是的,這是作業,但我只是要求它的一小部分,我不想要一個完整的答案,只是推動我在正確的方向。

+5

我懷疑這應該有多個線程。相反,一個線程執行一次「轉向」,從任何可以提供它的牌中拿走該牌。 –

+0

您需要爲每個線程提供一些類型的監視器,以便您可以告訴線程輪到他們可以運行了。這將阻止所有其他線程執行,直到您告訴他們可以執行爲止。看看[鎖定對象](http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html) – MadProgrammer

+0

你做錯了。你不想爲每一個動作啓動一個新的線程。你可能希望每個球員都有一個單獨的線索,儘管我不知道這有什麼強烈的動機。 – EJP

回答

3

當輪到不同玩家時,我該如何在線程之間切換?

線程的突出特點是幾個線程可以同時運行。如果您不使用該功能,則使用線程沒有意義。由於玩家在不輪到他時也可以移動,因此所有玩家同時處於活動狀態實際上是有意義的。因此,我會爲每個玩家創建(並啓動)一個線程。該線程將在睡眠和移動之間交替。

這留下了線程如何交互的問題。爲此,我會創建一個類:

class Game { 
    Card topCard; 
    Player nextPlayer; 

    ... 
} 

並將遊戲實例提供給每個玩家線程。當玩線想着他的舉動時,他可以看看頂牌,以及是否輪到他。在進行移動時,他只是更新Game實例中的字段。

當然,由於不同的線程可以同時激活,所以有可能兩個玩家同時嘗試移動(或換句話說,玩家可能決定玩一張卡,但另一個玩家更快,使初始玩家的舉動不再有效)。同步對Game實例的訪問最容易阻止。對於現實主義,您可能在觀察遊戲狀態時想要同步,然後思考,然後再次同步以進行移動。但是,在整個「外觀,思考和移動」循環中進行同步可能更容易,因爲這可以確保玩家不會干擾彼此思考,並減少需要處理的角落案例數量。

另一個摺痕是終止。只要第一個玩家沒有剩下卡片,遊戲就結束,所以其他玩家需要注意這一事實。最簡單的方法可能是讓最終玩家宣佈自己是贏家(例如,通過在Game實例中設置字段winningPlayer),並且在宣佈獲勝者後立即終止其他線程。

+0

謝謝,我會盡力,非常有幫助。 – user2283715

+0

爲每位玩家的整個回合同步'遊戲',是不正確的 - 其他玩家如果能夠放下匹配卡並可以「切入」,然後輪到他們。 –

+0

您誤解了:我說線程「在睡眠和移動之間交替」,並且我建議同步整個移動序列,其中包括「外觀,思考和移動」。 (思考不是對睡覺的委婉說法,而是指決定玩家如何移動的代碼。) – meriton

0

很難幫助做家庭作業的問題,因爲通常教授正在尋找某種解決方案並正確地解決問題,但以錯誤的方式仍然可以被視爲違反您。例如,說每個玩家應該有一個線程,這是非常有用的,因爲還有許多其他有效的方法,但是如果你這樣做了,那麼對於你的功課來說就是錯誤的。因此,如果您有其他信息可以分享有關預期解決方案,請分享。我認爲選擇這個問題是因爲你還沒有等待信號量。

如果你打算給每個玩家一個線程,那麼你可以建立人類玩家如何玩遊戲的模型。每個玩家都知道垃圾堆上的卡片,其他玩家是誰,他們玩的順序是什麼,玩過的是誰,玩的是什麼。所以你想要表示所有線程都可以看到的一些對象中的所有事實。

每個線程(玩家)也有自己的手,只有它可以看到,所以應該建模爲每個線程的對象。

關鍵是玩家(線程)做出的動作!您的主程序只是啓動線程並等待遊戲結束。玩家可以隨便休息一段時間,然後醒來,看看他們是否可以移動,如果可以移動,然後再回去睡覺。