Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建新线程以将对象保存到文件_Java_Multithreading_Performance - Fatal编程技术网

Java 创建新线程以将对象保存到文件

Java 创建新线程以将对象保存到文件,java,multithreading,performance,Java,Multithreading,Performance,我想将一个对象(我的游戏模型/数据)保存到磁盘,但由于游戏可能会变得相当大——可能大到需要几个游戏刻度来存储——我认为在单独的线程中执行保存是有意义的,以保持游戏相对平稳地运行 实现这一目标的最佳方法是什么?我不确定将游戏状态(模型)设置为可运行或线程扩展是否有意义,因为大多数情况下,它并不打算是可运行的——从逻辑上讲,它不应该是可运行的 我考虑过的其他可能性是有一个可运行的GameSaver类,我将GameState或GameState的副本传递给它。但是,如果我通过了游戏状态或者在类被克隆时

我想将一个对象(我的游戏模型/数据)保存到磁盘,但由于游戏可能会变得相当大——可能大到需要几个游戏刻度来存储——我认为在单独的线程中执行保存是有意义的,以保持游戏相对平稳地运行

实现这一目标的最佳方法是什么?我不确定将游戏状态(模型)设置为可运行或线程扩展是否有意义,因为大多数情况下,它并不打算是可运行的——从逻辑上讲,它不应该是可运行的

我考虑过的其他可能性是有一个可运行的GameSaver类,我将GameState或GameState的副本传递给它。但是,如果我通过了游戏状态或者在类被克隆时会减慢游戏速度,这可能会导致同步问题


什么是最好的方法,或者说是正反两种方法?任何其他替代方案也值得赞赏-我怀疑我的搜索是否详尽无遗。

从纯线程管理的角度来看,我认为最干净的方法是使用执行器。这并不能解决你的克隆问题

创建保存游戏的方法:

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);
关闭应用程序时不要忘记关闭executor:

executor.shutdown();
例如,您还可以使用每x分钟运行一次的
ScheduledExecutorService

该类可能如下所示,例如:

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();

您必须解决同步问题,无论您选择何种解决方案。我看不出您如何在不拍摄快照的情况下安全地写入状态。@Martin James这取决于您的状态是如何组织的。例如,如果存储时间戳事件,则不必这样做。(想象一场国际象棋。)保存发生的确切时间,或者单击保存和写入文件之间的状态是否改变,几乎无关紧要。自动保存可能有点随机,而用户/游戏的其余时间仅在状态稳定(或至少稳定到没有发生重要变化的程度)时保存-这是否意味着我不需要拍摄快照?请回答你的附带问题:几乎没有一个好的理由来扩展java.lang.Thread。线程是执行工作的资源。Runnable是一项工作。很少有人会创建一种新类型的资源来完成一些工作,我们有一个非常好的资源!我完全忘记了在类中创建Runnable的能力。我必须看一下Executor服务,但这看起来是一个相当不错的技术。除了整洁之外,这还有什么好处呢?您不必处理线程管理的低级细节——尽管如果有必要,您仍然需要处理同步。您可以轻松更改示例,并使用
ScheduledExecutorService
每x分钟自动保存一次。非常好,谢谢。这看起来是一个非常简洁的解决方案-现在我只需要决定是否需要拍摄快照。这实际上取决于您的实现细节。