How and why is this code thread safe ..?

This is my code.

@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){
        lastFactors=Arrays.copyOf(factors, factors.length);

    public BigInteger[] getFactors(BigInteger i){
        if(lastNumber==null || !lastNumber.equals(i))
            return null;
            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);



Why is the VolatileCachedFactorizer class a thread according to the Book . But my point ... 1. @Line 1 if 2 threads coming at the same time at this point 1st thread

check the condition and found factor = null , and 2nd thread

also check the same state in the same then same time after 1st thread

pause on line 2nd and find factor = null
AND both will create a new OneValueCached

Object Then, as this code is thread safe .. According to the book it is thread safe ..

Thanks x


source to share

5 answers

It is thread safe because there is never any inconsistency between lastNumber

and lastFactors

, which can lead to incorrect factorization. It does not guarantee that the minimum amount of factoring will take place: it OneValueCached

can be created multiple times, but it is still thread safe.



The exact concept of "thread safety" is not defined here. What do you expect to happen / not to happen so that this code is thread safe?

  • If you expect the state of all objects involved (as far as I can see in this code) to be consistent, then it will be thread safe (as @artbristol explains).
  • If you are expecting a single object to Cache

    be created when service

    called concurrently, then it is not thread safe.

Again, without defining thread-safe behavior for this situation, we cannot be sure.



This code is thread safe. But I don't think the Array.copyOf()

constructor is necessary.



Although this question was asked over a year ago, I still want to give my explanation. In fact, this code is taken from Java Concurrency in Practice, page 40. The author claims that the VolatileCachedFactorizer is a thread-safe servlet because the servlet program itself is invoked simultaneously by users. So the author means that if the variable is the OneValueCached key can be read and written by streams sequentially, which means it will not cause situations like lastNumber and lastFactors that are not the same, then it will be thread safe. What I'm confused about is that the book states that if Arrays.copyOf () was used it would be thread safe. But why? Why is Arrays.copyOf () needed?



Qisen, answering your question, needs Arrays.copyOf (), because otherwise OneValueCache will not be immutable. If you didn't copy the factors when creating the OneValueCache, you would allow the array to be referenced (as long as that point is not local to the running thread).



All Articles