Имеет ли значение использование вектора внутри синхронизированного блока? - PullRequest
4 голосов
/ 11 августа 2011

Мне задали этот вопрос в интервью.

Вектор уже синхронизирован. Будет ли иметь какое-либо значение, чтобы назвать это внутри синхронизированного блока?

       synchronized{
            // Call the vector here
       }

Мой ответ: не будет никакой разницы, за исключением некоторой потери производительности.

Правильный ли ответ?

Ответы [ 2 ]

12 голосов
/ 11 августа 2011

Нет, это не совсем правильно.Vector синхронизируется на самом экземпляре Vector, тогда как синхронизированный блок фактически синхронизируется на экземпляре, который содержит Vector.Два метода, входящие в синхронизированный блок, должны сначала получить монитор, связанный с this, а затем получить монитор, связанный с экземпляром Vector.

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

Тем не менее, учитывая только часть размещенного кода, поток, который первым получает монитор на thisбудет первым, кто выполнит операцию над вектором.Кроме того, последовательности операций на экземпляре Vector могут выполняться первым потоком без какого-либо чередования операций вторым потоком;это необходимо, если вы хотите выполнить атомарную последовательность операций на экземпляре Vector, что не будет иметь место на обычном синхронизированном экземпляре Vector.Чтобы представить это в псевдокоде, последовательность операций в двух представленных ниже случаях будет отличаться, если произойдет переключение контекста между двумя или более потоками, выполняющими один и тот же блок:

Случай A

synchronized
{
    vector.add(a);
    vector.add(b);
/*
 * a and b are always added to the vector in sequence.
 * If two threads execute this block, the vector will contain {a,b,a,b}.
 */
}

Корпус B

{
    vector.add(a);
    vector.add(b);

 /*
  * a and b need not be added to the vector in sequence.
  * If two threads execute this block, the vector will contain one of {a,b,a,b}, {a,a,b,b}....
  */
}
2 голосов
/ 11 августа 2011

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

Предположим, вы хотите реализовать контейнер, содержащий не более 10 элементов, и вы используете Vector для хранения этих элементов. Метод add будет выглядеть так:

public void add(Object item) {
    if (vector.size() == 10) {
        throw new TooManyItemsException();
    }
    else {
        vector.add(10);
    }
}

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

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

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

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