“同步”究竟有什么作用?锁定函数还是锁定对象函数?

2022-09-02 03:20:33

我想知道“同步”在java中是如何工作的。

假设我对一个由多个字段组成的棋盘游戏进行建模。我将字段实现为类(字段),将板实现为包含多个字段的类(板)。让我们进一步假设我在Field中建模了一个方法moveTo(Player pl),以便玩家移动到该字段。每个玩家由一个线程表示。

虽然所有线程应该同时执行一些操作(例如滚动其骰子),但一次只能有一个玩家移动。

我如何确保这一点?是否足以使方法 moveTo(Player pl) 同步?或者我需要在棋盘中使用级联方法来确保一次只有一个玩家移动?(或者有更好的解决方案)?

将其提升到底线:
“synchronized”是锁定具有此方法的每个对象中的方法,还是同步锁定仅在当前正在使用的对象中锁定方法?
如果是第二种情况:有没有一种简单的方法可以为实现此方法的每个对象锁定方法?

谢谢!!!


答案 1

我认为你想要的是以下内容:

class Field {

    // instance of the board
    private Board board; 

    public void moveTo(Player p){ 
        synchronized (board) {
            // move code goes here
        }
    }
}

这将使每个板,一次只有一个玩家移动。如果在开发板上获得同步锁,则一次只能有一个 Field 进入同步锁。(假设有一块板)

如果你只是简单地写了:

public synchronized void moveTo(Player p){ 

你只会确保玩家不能一次移动到同一个领域。这是因为当在定义中使用 synced 编写方法时,它将在对象级别锁定。因此,Field的每个实例都将是它自己的锁定对象,因此,只要玩家没有移动到同一个字段,他们仍然可以同时移动。


答案 2

synchronized 锁定对象,而不是方法。Java没有函数。

如果希望某个方法在所有对象中只调用一次,则可以锁定共享对象,如类。

我建议你只需要一个线程来执行所有的移动/操作,这将大大简化代码。为什么它必须是多线程的?