下面是Java Concurrency in Practice(Listing 2.8)一书中的线程安全类示例。
我的问题是下面的类如何保证线程安全?
例如,如果两个线程 Thread A
和 Thread B
进入 CachedFactorizer 的服务方法。 线程 B
后跟 线程 A
。现在,如果 Thread A
正在执行第一个同步块(synchronized block),而 Thread B
显然正在等待对象的内部锁。如果 Thread B
在 Thread A
进入第二个同步块(synchronized block)之前进入第一个同步块(synchronized block),它将查看一个陈旧值,并且这种情况可能是已知的作为竞争条件。
那么,我的理解到这里了吗?还是我缺乏对并发的一些基本了解?
@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);
}
}
最佳答案
这个类是线程安全的,因为所有共享变量都是在同步块(synchronized block)中访问的,在这种情况下没有数据竞争:
"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"
问题是从商业角度来看这种行为是否有效,例如。如果两个线程在第一个同步块(synchronized block)之后相遇,它们可以以不同的顺序执行第二个 block 。
关于java - Java Concurrency 中的示例在实践中如何保证线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47708937/