为什么需要同步?

Jam*_*s B 3 java multithreading thread-safety

我试图在我的Java线程知识​​中填补一些可耻的空白,而我正在阅读Brian Goetz等人(强烈推荐的BTW)中的Java Concurrency in Practice,本书中的一个早期例子给我留下了一个问题.在下面的代码中,我完全理解为什么在更新hitscacheHits成员变量时需要同步,但为什么getHits在读取hits变量时需要该方法呢?

第2章的示例代码:

public class CachedFactorizer extends GenericServlet implements Servlet {
  private BigInteger lastNumber;
  private BigInteger[] lastFactors;
  private long hits;
  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);
}...
Run Code Online (Sandbox Code Playgroud)

我有一种感觉它与原子性,监视器和锁定有关,但我并不完全理解这些,所以请有人在那里解释一下吗?

提前致谢...

詹姆士

Mic*_*rdt 6

除了在volatile没有同步时线程的非变量缓存视图可能无限期保持不更新的事实:

对long或double的读/写访问不保证是原子的!

理论上,您最终可以看到只更新第一个或最后4个字节的值.但是,也volatile解决了这个问题.