2016-11-15 32 views
1

我在寫一個多人遊戲,我需要一些解決方案來代表遊戲場。我實現了演示Synchronized2DArray類,但我認爲這不是最好的方法。同步塊鎖定整個數組,而我只需要鎖定一個單元格。是否可以鎖定一個單元格,或者可能有其他方法來提高性能?提高同步2D陣列的性能

class Synchronized2DArray { 
    private int[][] array; 

    public Synchronized2DArray(int size) {    
     array = new int[size][size]; 
    } 

    public void setValue(int x, int y, int value) { 
     synchronized (array) { 
      array[x][y] = value; 
     } 
    } 

    public int getValue(int x, int y) { 
     synchronized (array) { 
      return array[x][y]; 
     } 
    } 

.................  
} 

回答

1

我覺得你真正問題上不同級別:

  1. 你的抽象是 「糟糕」。你看,在良好的OO設計中,你創建了摘要;以創建您正在處理的事物的合理的模型。 int值的數組......僅提供了一點抽象。
  2. 然後還有一個關於鎖定如何工作的誤解。你是而不是「鎖定」整個陣列。相反,您編寫的代碼確保對getValue()setValue()的調用是,系列化爲。上面的代碼使得一個線程在另一個線程正在讀取該值時設置一個值是不可能的。那裏有一個微妙的差異。

所以,我的(非常通用的)的答案是:你應該退後一步,花了一些時間思考

  1. 創建一個對象模型,可以幫助你在一個真正的,面向對象的方式實現自己的想法。
  2. 什麼樣的平行活動將成爲可能,並且您希望優化哪個活動。

例如,您可以更改當前的鎖定方法,以使用ReentrantReadWriteLock;允許無限讀者訪問;但要確保寫作不會平行進行。

+0

「上面的代碼使得一個線程設置一個值,而另一個線程正在讀取該值時不可能。」 謝謝,我沒有想過那 – Paul

+1

是的。我只想確保你明白使用synchronized(array)不會奇蹟般地阻止該數組上的更新。你不是在轉動一些「魔法開關」來防止其他方法並行地更新數組對象! – GhostCat

+0

閱讀關於鎖 - ReentrantReadWriteLock類解決我的問題。 關於面向對象的設計和抽象 - 我認爲在我的情況下,沒有必要爲這個類創建抽象的父對象。只會有一個實現。這個同步數組是表示字段及其邏輯的類的內部類。 – Paul

1

GhostCat有一點,但我可以看到性能作爲在這裏使用數組的可能原因。您可能希望在數組中保留一個播放字段,並且您希望在此使用一些基本類型的數組以避免大量對象的開銷。這在Java中很難被抽象出來,儘管set和get方法可能會將ints映射到更有意義的東西。

更具體到你的問題: 你可以在單行或您的陣列的列這樣的同步:

synchronized (array[x]) { ... } 

你不能輕鬆地同步僅在一個小區中的Java同步僅適用於對象,但而不是像int這樣的基本數據類型。 如果您使用對象作爲單元格元素(例如Integer而不是int),則可以在單個單元上進行同步,但內存和性能開銷可能太大而無法成爲一個好主意。

+0

也是有效的。但我有模糊的感覺,他沒有使用int數組出於這個原因... – GhostCat