Как и почему этот код является потокобезопасным ..? - PullRequest
3 голосов
/ 27 марта 2012

Это мой код ..

@immutable // This is not a standard annotation .Only for Showing that behavior of Class 
class OneValueCached{
    private final BigInteger lastNumber;
    private final BigInteger[] lastFactors;
    public OneValueCached(BigInteger i,BigInteger[] factors){
        lastNumber=i;
        lastFactors=Arrays.copyOf(factors, factors.length);
    }

    public BigInteger[] getFactors(BigInteger i){
        if(lastNumber==null || !lastNumber.equals(i))
            return null;
        else 
            return Arrays.copyOf(lastFactors, lastFactors.length);
    }
}

@threadSafe // This is not a standard annotation .Only for Showing that behavior of Class 
public class VolatileCachedFactorizer implements Servlet{
    private volatile OneValueCached cache=new OneValueCached(null, null);

    public void service(ServletRequest req, ServletResponce resp){
        BigInteger i= extractFromRequest(req);
        BigInteger[] factors=cache.getFactors(i);
        if(factors==null){   // ---> line 1
            factors=factor(i);  // --> line 2
            cache=new OneValueCached(i, factors);
        }

        encodeIntoResponse(resp,factors);
    }
}

Почему класс VolatileCachedFactorizer является потоком в соответствии с Книга Но моя точка зрения ..
1. @ Линия 1 , если 2 потока, поступающие одновременно в этот момент, 1-й thread проверяет условие и обнаруживает factor = null , а 2-й thread также проверяют то же самое состояние одновременно после 1-го thread приостановить в строке 2-й и найти factor = null
И то, и другое будет создавать новый OneValueCached Object. Тогда, как этот код является потокобезопасным. Согласно книге, это потокобезопасный.

Спасибо в

Ответы [ 5 ]

3 голосов
/ 27 марта 2012

Это потокобезопасно, потому что между lastNumber и lastFactors никогда не возникает несоответствие, которое может привести к неправильному факторингу. Это не гарантирует, что минимальное количество факторинга будет иметь место: OneValueCached может быть создано более одного раза, но это все еще поточно-ориентировано.

1 голос
/ 27 марта 2012

Точное понятие «потокобезопасность» здесь не определено. Что вы ожидаете, что произойдет / не произойдет, чтобы этот код был поточно-ориентированным?

  1. Если вы ожидаете, что состояние всех задействованных объектов (насколько я могу видеть в этом коде) будет согласованным, тогда оно поточно-ориентированное (как объясняет @artbristol).
  2. Если вы ожидаете одно создание объекта Cache при одновременном вызове service, то это не потокобезопасно.

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

0 голосов
/ 20 августа 2014

Qisen, Отвечая на ваш вопрос, Arrays.copyOf () необходим, потому что в противном случае OneValueCache не будет неизменным.Если вы не скопировали факторы при создании OneValueCache, вы бы позволили экранированию ссылки на массив (который до этой точки является локальным для выполняющегося потока).

0 голосов
/ 24 марта 2014

Хотя этот вопрос задавался более года назад, я все же хочу дать свое объяснение.Фактически, этот код взят из «Параллелизма Java на практике», стр. 40. Автор утверждает, что VolatileCachedFactorizer - это потокобезопасный сервлет, так как сама программа сервлета вызывается пользователями одновременно. Так что автор означает, что если viariable -Кэш OneValueCached может последовательно считываться и записываться потоками, что означает, что такие ситуации, как lastNumber и lastFactors не будут совпадать, не будут вызывать совпадения, тогда это будет потокобезопасным.используется, это будет потокобезопасным. Но почему? Зачем нужен Arrays.copyOf ()?

0 голосов
/ 28 июля 2012

Этот код является потокобезопасным.Но я не думаю, что Array.copyOf() в конструкторе необходимо.

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