2012-04-17 100 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

相关问题