Вопрос о практике ссылок на Java и синхронизированного ключевого слова? - PullRequest
0 голосов
/ 24 февраля 2011

Меня смущает проблема со ссылками и синхронизированным ключевым словом долгое время.Я обычно вижу такой код:

Class someClass {
    ...
    private SomeObject mObject;
    ...
    public void someMethod() {
        ...
       final SomeObject obj = mObject;
       ...
       //then use the 'obj' variable rather than mObject
       ...
    }

}

Мой вопрос: зачем использовать локальную конечную переменную obj для замены переменной-члена?Почему бы не использовать переменную-член напрямую?

Я также вижу пример кода, связанного с ключевым словом synchronized, например:

public void write(byte[] out) {
    // Create temporary object
    ConnectedThread r;
    // Synchronize a copy of the ConnectedThread
    synchronized (this) {
        if (mState != STATE_CONNECTED) return;
        r = mConnectedThread;
    }
    // Perform the write unsynchronized
    r.write(out);
}

Почему этот код может достичь синхронизированной цели?Спасибо!

Ответы [ 4 ]

0 голосов
/ 24 февраля 2011

1> Я думаю, что для первого вопроса ... переменная-член не используется напрямую, потому что этот ссылочный объект может использоваться и в некоторых других методах .... и в других методах может не требоваться быть объявленным какfinal, как в случае метода, как вы показали .... так что рекомендуется создать локальную ссылку на эту переменную .....

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

0 голосов
/ 24 февраля 2011

В первом примере, я полагаю, идея состоит в том, чтобы взять копию переменной-члена в конечную локальную переменную, чтобы при изменении переменной-члена в другом потоке копия в функции-члене оставалась прежней.

Второй пример аналогичен тем, что он берет копию текущего подключенного потока в локальной переменной.

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

Я уверен, что есть имя для этого шаблона кодирования, но я не могу его запомнить!

0 голосов
/ 24 февраля 2011

Из того, что я могу понять по вашему вопросу, и по первому примеру, код пытается избежать проблем с потоками, желая получить локальную копию переменной-члена.Первый пример этого не делает, он просто получает новую локальную переменную, указывающую на тот же объект, на который указывает переменная-член, но фактически не защищает вызовы этого объекта от проблем с многопоточностью.Комментарий Ника: как говорит Ник, метод someMethod в первом примере исключает возможность замены mObject другим экземпляром на полпути.Однако он не защищает от проблем с многопоточностью одновременными вызовами в одном экземпляре.

0 голосов
/ 24 февраля 2011

Что касается первого вопроса, то он должен удостовериться, что метод не может изменить объект, присвоив ему псевдоним конечную переменную, и вы гарантируете, что не переназначите что-то позже?Я не уверен ...

Второй вопрос: это работает, потому что если mState не подключен, то мы возвращаемся из метода, а r.write () не выполняется.Он использует сам объект как замок.

...