实际上,同步是针对代码的,而不是对象或数据的。在同步块中用作参数的对象引用表示锁定。
因此,如果您有如下代码:
class Player { // Same instance shared for all players... Don't show how we get it now. // Use one dimensional board to simplify, doesn't matter here. private List<Player>[] fields = Board.getBoard(); // Current position private int x; public synchronized int getX() { return x; } public void setX(int x) { synchronized(this) { // Same as synchronized method fields[x].remove(this); this.x = x; field[y].add(this); } }}
然后,尽管处于同步块中,但由于锁不相同(它在不同的实例上),所以对字段的访问不受保护。因此,您的董事会的球员名单可能会变得不一致,并导致运行时异常。
相反,如果您编写下面的代码,它将起作用,因为我们只有一个共享锁可供所有玩家使用:
class Player { // Same instance shared for all players... Don't show how we get it now. // Use one dimensional board to simplify, doesn't matter here. private List<Player>[] fields; // Current position private int x; private static Object sharedLock = new Object(); // Any object's instance can be used as a lock. public int getX() { synchronized(sharedLock) { return x; } } public void setX(int x) { synchronized(sharedLock) { // Because of using a single shared lock, // several players can't access fields at the same time // and so can't create inconsistencies on fields. fields[x].remove(this); this.x = x; field[y].add(this); } }}
请确保仅使用一个锁来访问所有播放器,否则板的状态将不一致。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)