2

我开始为我的游戏考虑多线程,最好的起点是将游戏的三个主要组件:逻辑、gfx、sfx 分成 3 个单独的线程。问题是它们都需要访问与hashmap逻辑相同的实体,gfx 和 sfx 彼此完全分离。

private Map<String, Entity> entities;
private Map<String, GameSound> sounds;
private Map<String, ArrayList<BufferedImage>> images;

相同的 hashmap 被传递给不同的类,并且对象损坏很可能与多个线程一起使用。目前SoundsEngine是一个线程(否则音乐在两者之间暂停Thread.sleep(),这很好,因为它不会改变,它只是读取。

是否有一种简单的(并且不影响性能)方法来实现线程安全HashMap,而无需在我的代码中添加同步(并且可能以这种方式引入更多错误)?我考虑过每 60 帧进行一次浅拷贝,因为这是我游戏中任何东西都会改变的最大速率,并将游戏循环中的拷贝传递给不同的引擎,但这似乎有点“hacky”。

并发问题由工厂中的构造函数显示:

public class Factory {

    private Map<String, Entity> entities;
    private Map<String, GameSound> sounds;
    private Map<String, ArrayList<BufferedImage>> images;
    private GameEventListener listener;
    private GameFrame frame;
    private ImageLoader Iloader;
    private SoundLoader Sloader;


    public Factory() {
        this.Iloader = new ImageLoader("imagelist.txt", images);
        this.Sloader = new SoundLoader("soundlist.txt", sounds);
        this.frame = new GameFrame(Color.black);
        this.listener = new GameEventListener();
    }

    public GameEngine createGameEngine() {
        return new GameEngine(entities, images, sounds);
    }

    public SoundEngine createSoundEngine() {
        return new SoundEngine(entities, sounds);
    }

    public GraphicsEngine createGraphicsEngine() {
        return new GraphicsEngine(entities, frame);
    }
}

编辑:单例不是一个选项,在之前的游戏中已经这样做了,我想学习一个更“松散”的设计,我可以独立开发引擎而不会因为我的状态错误而破坏某些东西。

4

2 回答 2

4

如果您想获得 Hashmap 的同步版本,那么您可以使用以下java.util.Collections类的内置方法:

Map m = Collections.synchronizedMap(new HashMap(...));

除此之外,对您来说java.util.concurrent.ConcurrentHashMap是一个更好的选择。

于 2013-04-08T18:10:38.493 回答
1

使用 ConcurrentHashMap 更好,因为它不使用同步块。它更加高效和快捷。Collections.synchronizedMap 是一个代理,其中一个同步块将被添加到每个方法调用。

于 2013-04-08T19:49:35.297 回答