Что именно делает "синхронизированный"? Блокировать функцию или блокировать функцию объектов? - PullRequest
19 голосов
/ 03 января 2011

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

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

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

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

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

Спасибо !!!

Ответы [ 4 ]

29 голосов
/ 03 января 2011

Я думаю, вы хотели бы получить следующее:

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){ 

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

7 голосов
/ 03 января 2011

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

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

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

1 голос
/ 03 января 2011

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

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

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

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

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

1 голос
/ 03 января 2011

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

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

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

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

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

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

...