【问题标题】:Concurrency issues and hashmap并发问题和哈希图
【发布时间】:2013-03-30 22:27:32
【问题描述】:

我开始为我的游戏考虑多线程,最好的起点是将游戏的三个主要组件:逻辑、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);
    }
}

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

【问题讨论】:

  • 哇哦,它的表演很棒!谢谢,30 分钟的谷歌搜索被 SO 打败了,我该睡一觉了。

标签: java concurrency hashmap


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    除了java.util.concurrent.ConcurrentHashMap 对你来说是一个更好的选择。

    【讨论】:

    • 为什么Collections.synchronizedMap()ConcurrentHashMap 更好?
    • @MattBall :如果您已阅读我的所有帖子,那么您一定已经看到我已经明确提到ConcurrentHashMap 是一个更好的选择
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多