2013-04-08 42 views
2

我開始考慮爲我的遊戲開發多線程,最好的地方是將遊戲的三個主要組件:邏輯,gfx,sfx分成3個獨立的線程。問題是他們都需要像邏輯一樣訪問實體的相同hashmap,gfx和sfx完全相互獨立。併發問題和散列圖

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

將相同的散列映射傳遞給不同的類,並且對象損壞很可能與多個線程有關。目前SoundsEngine是一個線程(否則Thread.sleep(),這是罰款,它不會改變的音樂停頓,它只是讀取。

是否有實現線程一個簡單的(和性能不hardhitting)方式HashMap而不是在我的代碼中添加同步(可能會引入更多的錯誤)?我考慮每60幀採用一個淺度副本,因爲這是我遊戲中任何內容的最大速率都會改變,並將副本在gameloop中傳遞給不同的副本引擎,但這似乎是一個「哈克」的缺點

併發問題是由工廠的構造函數顯示的:

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

編輯:單身漢不是一種選擇,在以前的遊戲中已經這樣做了,我想學習一種更「鬆散」的設計,在這種設計中,我可以獨立開發引擎而不會破壞某些東西,因爲我的狀態不正確。

+6

['ConcurrentHashMap'](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html) – 2013-04-08 18:07:53

+0

哦哇,它是一個偉大的演員!謝謝,被SO打敗了30分鐘的谷歌搜索,我應該睡一覺。 – arynaq 2013-04-08 18:10:18

回答

4

如果你想獲得同步您的Hashmap的版本,那麼你可以使用java.util.Collections類的以下內置方法:

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

除此之外java.util.concurrent.ConcurrentHashMap對你是一個更好的選擇。

+2

爲什麼'Collections.synchronizedMap()'比'ConcurrentHashMap'好? – 2013-04-08 18:19:37

+1

@MattBall:如果你已經閱讀了我的所有文章,那麼你一定已經看到我明確提到'ConcurrentHashMap'是一個**更好的選擇**。 – 2013-04-08 18:21:55

1

使用ConcurrentHashMap更好,因爲它不使用同步塊。它效率更高,速度更快。 Collections.synchronizedMap是一個代理,其中一個同步塊將被添加到每個方法調用中。