是否可以直接使用上次计算的结果? Java 同步块

Is it possible to use the result of the last calculation directly ? Java Synchronized block

为什么连续两次请求对同一个值进行因式分解时,Synchronized块可以直接使用之前的计算结果?

代码来自 Java 并发实践

的 2-8
    public class two_8_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;
    }
    @Override
    public  void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        BigInteger i=extractFromRequest(req);
        BigInteger[] factors=null;
        synchronized (this) {
            ++hits;
            if (i.equals(lastNumber)) {
                ++cacheHits;
                factors = lastFactors.clone();
            }
        }
            if (factors==null)
            {
                factors=factor(i);//question in here :Suppose two identical requests arrive here at the same time
                synchronized (this)
                {
                    lastNumber=i;
                    lastFactors=factors.clone();
                }
            }
            encodeIntoResponse(res,factors);
        }

}

我相信你手上至少有一个竞争条件。可能是较早发布的 factor(i) 在较晚发布的 factor(i) 之后完成;覆盖后来发布的值factor(i)。所以 lastFactor 和 lastNumber 可以更新到更早的版本。为了解决这个问题,我会在最后一个同步块中添加一些检查。

在当前代码中,您可以让多个线程执行相同的计算。我不确定这是否可取。