2016-11-15 71 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