2012-04-17 88 views
0

我想將一個對象(我的遊戲的模型/數據)保存到磁盤,但是由於遊戲可能會變得非常大 - 足夠大以至於需要多個遊戲刻度才能存儲 - 我認爲在一個單獨的線程中執行保存是有意義的,以保持遊戲運行的相對平穩。創建一個新線程將對象保存到文件

達到此目的的最佳方法是什麼?我不確定是否讓GameState(模型)成爲Thread的可運行或擴展是有意義的,因爲大多數時候它不是可運行的 - 從邏輯上講,它不應該是Runnable?

我看過的其他可能性是有一個Runnable GameSaver類,我通過GameState或GameState的副本。不過,如果我通過GameState,這可能會導致同步問題,或者會在克隆課程時降低遊戲速度。

什麼是最好的方法,或親和的方法?任何其他備選方案也讚賞 - 我懷疑我的搜索已經詳盡無遺。

+0

你將要解決的同步,無論您選擇的解決方案。 – biziclop 2012-04-17 23:01:35

+0

我看不到如何在不拍攝快照的情況下安全地寫入狀態。 – 2012-04-17 23:02:04

+0

@馬丁詹姆斯這取決於你的國家是如何組織的。例如,如果您存儲時間戳事件,則不必這樣做。 (想象一下國際象棋遊戲。) – biziclop 2012-04-17 23:05:14

回答

2

從純粹的線程管理角度來看,我認爲最簡潔的方式就是使用執行程序。這並不能解決你的克隆(或不)問題。

創建一個保存遊戲的方法:

public void saveTheGame() { 
    //you maybe need to take a snapshot, which might require synchronization 
    GameState state = ....; 
} 

創建一個可運行的,作爲一個類的實例成員例如,嵌入了呼叫和執行服務:

private final Runnable save = new Runnable() { 
    public void run() { 
     saveTheGame(); 
    } 
} 
private final ExecutorService executor = Executors.newFixedThreadPool(1); 

並保存當需要時遊戲:

executor.submit(save); 

不要忘記關閉執行器時,c失去你的應用程序:

executor.shutdown(); 

你也可以使用一個ScheduledExecutorService,而不是運行每x分鐘的例子。

類可能是這樣的,例如:

public static class GameSaver { 
    private final Runnable save = new Runnable() { 

     @Override 
     public void run() { 
      saveGame(); 
     } 
    }; 
    private static final ExecutorService executor = Executors.newFixedThreadPool(1); 
    private final GameState state; 

    public GameSaver(GameState state) { 
     this.state = state; 
    } 

    public void save() { 
     executor.submit(save); 
    } 

    public static void close() { 
     executor.shutdown(); 
    } 

    private void saveGame() { 
     //save your game here 
    } 

} 

和主代碼:

GameState state = getGameState(); 
GameSaver saver = new GameSaver(state); 
saver.save(); 
+0

我完全忘記了在類中創建Runnable的能力。我將不得不看看ExecutorService,但這看起來像一個相當整潔的技術。除了整潔以外,還有什麼好處呢? – 2012-04-17 23:15:17

+1

您不必處理線程管理的低級別細節 - 儘管如果有必要仍需要處理同步。您可以輕鬆更改示例,並使用「ScheduledExecutorService」自動保存每x分鐘。 – assylias 2012-04-17 23:16:56

+0

非常好,謝謝。這看起來是一個非常好的解決方案 - 現在我只需要決定是否需要拍攝快照。 – 2012-04-17 23:19:45