2015-01-07 2 views
1

Рассмотрите следующий класс.Метод синхронизации предотвращает обновление полей объектов?

public class Counter{ 

    private Lock lock = new Lock(); 
    private int count = 0; 

    public int inc(){ 
    lock.lock(); 
    int newCount = ++count; 
    lock.unlock(); 
    return newCount; 
    } 

    public int incBy2() { 
     syncronized(this){ 
     count+=2; 
     return count; 
     } 
} 

В настоящее время Thread T1 вызывает метод inc() и T2 вызывает incBy2(). Здесь есть условия гонки? или будет блокировка T2 this, тем самым предотвращая метод inc для вызова lock.lock()?

ответ

1

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

Когда вы пишете

class Foo { 

    public void doSomething() { 
     synchronized(this) { 
      ... 
     } 
    } 
} 

вам лучше писать

class Foo { 
    private Object lock = new Object(); 

    public void doSomething() { 
     sychronized(lock) { 
      ... 
     } 
    } 
} 

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

1

Состояние гонки. Вы по существу синхронизированы на двух отдельных объектах. Оба потока могут одновременно вводить inc() и incBy2() критических секций.

+0

Когда я syncronize на 'this', я неявно блокирую другие потоки, чтобы получить доступ к полям, которые в этом случае являются объектом блокировки. –

+1

@brain: нет. Джон прав. Приобретение монитора на этом не делает ничего, чтобы отказать в доступе к потоку. –

+1

@brainstorm, как сказал Натан, но добавить. Вы блокируете другие потоки от доступа к критическим разделам, а не к полям. Синхронизация на 'this' говорит, что любой вызывающий, который пытается« синхронизировать »на' this', должен будет дождаться завершения. Как вы можете видеть, поскольку '' sychronize (this) 'in' inc() 'не существует, то другой поток не должен ждать. –

 Смежные вопросы

  • Нет связанных вопросов^_^