Синхронизированный геттер и сеттер - PullRequest
2 голосов
/ 12 февраля 2012

Я сейчас изучаю параллелизм Java. У меня вопрос по поводу synchronized и замков.

Для любых изменяемых данных мы должны поместить все методы доступа к данным в одну и ту же блокировку.

Но что означает та же самая блокировка?

Пример:

public class SynchronizedInteger{
    private int value;
    public synchronized int get(){return value;}
    public synchronized void set(int value){this.value=value;}
}

Итак, мой вопрос: почему эти два метода находятся в одной и той же блокировке? Я знаю, что они есть, но я хотел бы знать, почему? И означает ли это, что все синхронизированные методы в классе находятся в одной и той же блокировке?

Edit:

Итак, если я добавлю еще один метод в класс:

public synchronized void printOneToHunder(){ </p> <pre><code>for(int i=0;i<100;i++) System.out.println(i);

}

Этот метод также будет включен в тот же блок, что и сеттер и геттер? Итак, другой поток не может запустить этот метод, когда есть один поток, использующий либо сеттер, либо геттер?

И что если я поменяю класс на следующий:

public class SynchronizedInteger{
    private int value1;
    private int value2;
    public synchronized int get1(){return value1;}
    public synchronized void set1(int value){this.value1=value1;}
    public synchronized int get2(){return value2;}
    public synchronized void set2(int value){this.value2=value2;}       
}

Насколько я понимаю, только один поток может вызывать эти методы одновременно. Так как же заставить один поток изменить значение1, а другой - изменить значение2 ???

Большое спасибо за ваши добрые разъяснения !!!!

Ответы [ 4 ]

5 голосов
/ 12 февраля 2012

Все нестатические методы, которые вы объявляете synchronized, ведут себя по существу так, как если бы код был:

public synchronized int get() {
  synchronized(this) {
    // the method code
  }
}

т.е. на this установлена ​​неявная блокировка. Таким образом, все нестатические синхронизированные методы будут блокировать экземпляр, в котором они вызываются.

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

4 голосов
/ 12 февраля 2012

Да, ваши два метода используют одну и ту же блокировку.

Ключевое слово synchronized без параметра неявно преобразуется в syncrhonized(this), который является одинаковым объектом для обоих методов.

Чтобы два блока имели одинаковую блокировку в java, это означает, что они оба используют один и тот же объект в качестве блокировки. И, как я уже сказал, в вашем случае оба метода используют this в качестве объекта блокировки.

0 голосов
/ 12 февраля 2012

Но у вас есть другие способы синхронизации.

Синхронизированные блоки: synchronized(someLockedObj){somecode}

Lock-Objects: Lock lock = new ReentrantLock(); lock.lock(); lock.unlock();

0 голосов
/ 12 февраля 2012

Когда вы объявляете метод synchronized, это означает, что синхронизация выполняется для конкретного экземпляра, для которого вызывается метод.

...