Синхронизация в Java? - PullRequest
       63

Синхронизация в Java?

1 голос
/ 02 ноября 2009

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

public class Foo  
{  
    protected CustomClass[] _mySynchedData = new CustomClass[10];

    public void processData()
    {
        synchronized(_mySynchedData) {
            // ...do stuff with synched variable here
        }
    }
}


public class Bar extends Foo
{

    @Override
    public void processData()
    {
        synchronized(_mySynchedData) {
            // perform extended functionality on synched variable here

            // ...then continue onto parent functionality while keeping synched
            super.processData();
        }
    }
}


Bar testObj = new Bar();

// Deadlock?
testObj.processData();

Ответы [ 4 ]

6 голосов
/ 02 ноября 2009

Ваш код отображает только одну тему.

Имея только одну ветку, вы никак не можете зайти в тупик.

Добавлено:
Язык Java поддерживает то, что они официально называют повторяющаяся синхронизация . По сути, это означает, что отдельный поток может повторно получить блокировку, которой он уже владеет.

5 голосов
/ 02 ноября 2009

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

Ответ таков: Java сначала проверит, какой поток владеет монитором (это внутренняя структура данных, на которой работает synchronized). Поскольку поток владельца совпадает с текущим потоком, Java продолжит работу.

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

4 голосов
/ 02 ноября 2009

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

1 голос
/ 02 ноября 2009

RichN верен в том, что ваш код содержит только один поток и, следовательно, тупик невозможен. Также обратите внимание, что для возникновения взаимоблокировки необходимо иметь несколько потоков, получающих несколько блокировок (хотя и в разном порядке ) для возникновения взаимоблокировки.

Ваш код в настоящее время ссылается только на одну блокировку: ту, которая связана с _mySynchedData. Тот факт, что вы пытаетесь заблокировать его дважды, не имеет значения, поскольку блокировки в Java reentrant .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...