Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How the example from Java Concurrency in practice is thread safe

Below is an example from book Java Concurrency in Practice(Listing 2.8) of a thread safe class.

My question is how the below class is thread safe?

For example if two threads Thread A and Thread B enter into service method of CachedFactorizer. Thread B followed by Thread A. Now if Thread A is executing first synchronized block and Thread B obviously waits for the intrinsic lock of the object. And if Thread B makes it to the first synchronized block before the Thread A makes it to the second synchronized block, it will be viewing a stale value and potentially this condition is known as Race Condition.

So, is my understanding right here? Or am I lacking some basic understanding of concurrency?

@ThreadSafe
public class CachedFactorizer implements Servlet {

    @GuardedBy("this") private BigInteger lastNumber;

    @GuardedBy("this") private BigInteger[] lastFactors;

    @GuardedBy("this") private long hits;

    @GuardedBy("this") private long cacheHits;

    public synchronized long getHits() { return hits; }

    public synchronized double getCacheHitRatio() {

        return (double) cacheHits / (double) hits;

    }


    public void service(ServletRequest req, ServletResponse resp) {

        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = null;
        synchronized (this) {
            ++hits;
            if (i.equals(lastNumber)) {
                ++cacheHits;
                factors = lastFactors.clone();
            }
        }
        if (factors == null) {
            factors = factor(i);
            synchronized (this) {
                lastNumber = i;
                lastFactors = factors.clone();
            }
        }
        encodeIntoResponse(resp, factors);
    }
}
like image 390
Rohit Khurana Avatar asked Nov 07 '22 13:11

Rohit Khurana


1 Answers

This class is thread safe because all shared variables are accessed in sychronized blocks, and in such situation there is no data race:

"When a program contains two conflicting accesses (§17.4.1) that are not ordered by a happens-before relationship, it is said to contain a data race.https://docs.oracle.com/javase/specs/jls/se9/html/jls-17.html"

The question is if this behaviour is valid from business point of view, eg. if two threads meet after first synchronized blok, they can execute second block in different order.

like image 131
olsli Avatar answered Nov 15 '22 05:11

olsli