Подтвердить что ты не робот

Что именно "синхронизируется"? Заблокировать функцию или заблокировать функцию объектов?

Мне интересно, как именно "синхронизировано" работает в java.

Скажем, я моделирую настольную игру, состоящую из нескольких полей. Я реализую поля как класс (поле) и плату как класс (Board), который содержит несколько полей. Позвольте еще сказать, что я смоделировал метод moveTo (Player pl) в поле, чтобы игрок переместился в это поле. Каждый игрок представлен потоком.

Хотя все потоки должны выполнять некоторые действия одновременно (например, перекатывать их кубики), должен быть только один игрок, который перемещается за раз.

Как я могу это гарантировать? Достаточно ли сделать так, чтобы метод moveTo (Player pl) был синхронизирован? Или мне нужен каскадный метод в Board, чтобы убедиться, что только один игрок перемещается одновременно? (Или есть лучшее решение)?

Чтобы довести это до конца:
"Синхронизировал" блокировку метода в КАЖДОМ объекте, который имеет этот метод, или будет синхронизирован метод блокировки только в объекте, который в настоящее время используется?
И если это второй случай: существует ли простой способ блокировки метода для каждого объекта, который реализовал этот метод?

Спасибо!!!

4b9b3361

Ответ 1

Я думаю, что вам нужно следующее:

class Field {

    // instance of the board
    private Board board; 

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

Это сделает так, что на доске только один игрок движется за раз. Если вы получаете блокировку синхронизации на плате, только одно поле может одновременно вводить синхронизированную блокировку. (Предполагая одну доску)

Если вы просто написали:

public synchronized void moveTo(Player p){ 

вы бы только уверяли, что игроки не могут одновременно перемещаться в одно поле. Это связано с тем, что, когда метод написан с синхронизацией в определении, он будет блокироваться на уровне объекта. Таким образом, каждый экземпляр поля будет его собственным объектом блокировки, и, таким образом, игроки могут перемещаться одновременно, пока они не переходят в одно и то же поле.

Ответ 2

синхронизация блокирует объект, а не метод. Java не имеет функций.

Если вы хотите, чтобы метод вызывался только один раз для всего объекта, вы можете заблокировать общий объект, например класс.

Я бы предложил вам только один поток для выполнения всех операций/операций, и это значительно упростило бы код. Почему он должен быть многопоточным?

Ответ 3

Синхронизация блокирует доступ к ресурсу. Этот ресурс может быть либо функцией, либо объектом (включая объект this).

Мы не можем дать вам конкретные рекомендации без конкретного примера.

В вашем примере, если игроки могут принимать только один оборот за раз, почему они должны быть в своих потоках? Зачем им нужно бросить свои кости одновременно?

Синхронизация функции блокирует вызовы к этой версии экземпляра этого метода (если это не статический метод).

And if the second is the case: is there an easy way to lock a function for every object that has this function implemented?

Это, по-видимому, предполагает, что ваш дизайн можно переоценить. Влияют ли ваши методы экземпляра объекта на состояние, чтобы они синхронизировались друг с другом? Почему?

Ответ 4

Это зависит от того, где он используется.

Если используется в типичном методе, он исключительно захватывает объект "блокировки" объекта, о котором идет речь. Никакая другая Thread не может обрабатывать методы в этом объекте, если им нужен эксклюзивный доступ к одному объекту "блокировка" объекта (несинхронизированные методы не требуют эксклюзивного доступа к блокировке).

Если используется в статическом методе, он исключительно захватывает объект блокировки объекта, представляющего класс. Ни одна другая Thread не может обрабатывать методы в этом объекте класса, если им нужен эксклюзивный доступ к одному объекту "блокировка" объекта класса (несинхронизированные методы не требуют эксклюзивного доступа к блокировке).

Если используется с явно заявленным объектом, он исключительно захватывает объект блокировки явно указанного объекта. Опять же, ни одна другая Thread не может захватить блокировку этого объекта за это время.

Как только вы покидаете область действия синхронизированного блока, вы отказываетесь от своего эксклюзивного удержания блокировки.