【发布时间】:2017-03-26 20:27:16
【问题描述】:
public class VolatileCachedFactorizer extends GenericServlet implements Servlet {
private volatile OneValueCache cache = new OneValueCache(null, null);
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i);
if (factors == null) {
factors = factor(i); //----------> thread A
cache = new OneValueCache(i, factors); //---------> thread B
}
encodeIntoResponse(resp, factors);
}
}
public class OneValueCache {
private final BigInteger lastNum;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger i, BigInteger[] lastFactors){
this.lastNum = i;
this.lastFactors = lastFactors;
}
public BigInteger[] getFactors(BigInteger i){
if(lastNum == null || !lastNum.equals(i))
return null;
else
return Arrays.copyOf(lastFactors, lastFactors.length);
}
}
这是Java concurrency in practice一书中的代码,我的问题专门在这段代码中,我们可以从OneValueCache中删除final关键字,仍然保持线程安全,对,我不知道为什么这些是final必须的关键字。
谢谢。
【问题讨论】:
-
是的,理论上可以忽略
final关键字,但您不应该这样做。你可以参考 Java Concurrency in Practice 的第 3.4.2 章。正如段落所说,我们想要创建一个不可变的对象。尽管lastNum和lastFactors是私有属性,但只有编写此类的人需要记住不要更改它们,最好将它们声明为final。一方面,Java 阻止您为这些属性重新分配值。此外,如果有人阅读此代码,可能带有“此类是不可变的”的注释,则更容易理解代码。
标签: java concurrency