Модификатор синхронизации Java

Я пытаюсь понять, как работают блокировки с использованием ключевых слов синхронизации в java. если у меня есть класс (забудьте о плохой практике и т. д. с публичными варами и т. д.)

class Person 
{
    public int money;
    public String name;

    public void give_bonus()
    {
        synchronize(this)
        {
            money += 10;
            name = "....";
        }
    }
}

// thread one 
person.give_bonus();

// thread two
person.money += 50;

Теперь мой вопрос: если я создам блокировку с помощью блокировки экземпляра (это), помешает ли это другим потокам манипулировать деньгами собственности? или мне нужно сделать свойство money частным и определить геттер/сеттер с модификатором синхронизации, чтобы убедиться, что это значение не рискует попасть в состояние гонки?


person Mads Lee Jensen    schedule 26.05.2013    source источник


Ответы (3)


Предоставленный вами код не позволит другим потокам изменять переменную money с помощью метода give_bonus() только до тех пор, пока метод не вернется (или, скорее, непосредственно перед возвратом метода).

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

person Keppil    schedule 26.05.2013

Синхронизация на this не имеет никакого отношения к содержимому объекта this. Механизм блокировки Java в основном работает с обычными объектами, которые играют другую роль, полностью отдельную от их «объектности». Эта другая роль включает в себя специальное поле в каждом объекте, называемое его монитор, записывающее, какой поток его захватил и сколько раз.

person Marko Topolnik    schedule 26.05.2013

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

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

В вашем примере ничто не мешает потоку 2 напрямую обращаться к money - тот факт, что поток 1 находится в синхронизированном блоке, не позволяет потоку 2 одновременно войти в синхронизированный блок на том же мониторе.

person Ian Roberts    schedule 26.05.2013