首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“实践中的Java并发性”--缓存的线程安全数字分解程序(清单2.8)

“实践中的Java并发性”--缓存的线程安全数字分解程序(清单2.8)
EN

Stack Overflow用户
提问于 2012-08-20 16:23:24
回答 5查看 484关注 0票数 7

在以下代码中(复制自Java Concurrency in Practice第2章,2.5节,清单2.8):

代码语言:javascript
复制
@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(); // questionable line here
            }
        }
        if (factors == null) {
            factors = factor(i);
            synchronized (this) {
                lastNumber = i;
                lastFactors = factors.clone(); // and here
            }
        }
        encodeIntoResponse(resp, factors);
    }
}

为什么要克隆factorslastFactors阵列?它不能简单地写成factors = lastFactors;lastFactors = factors;吗?仅仅因为factors是一个局部变量,然后将其传递给encodeIntoResponse,它可以修改它吗?

希望问题是清楚的。谢谢。

EN

回答 5

Stack Overflow用户

发布于 2012-10-05 19:09:53

这称为防御性复制。与其他数组一样,数组也是对象,因此

代码语言:javascript
复制
 factors = lastFactors

可以将lastFactos引用到因子,反之亦然。所以任何人都可以覆盖你的状态,而不是你的控制。举个例子:

代码语言:javascript
复制
private void filterAndRemove(BigInteger[] arr);
private void encodeIntoResponse(..., BigInteger[] factors) {
   filterAndRemove(factors);
}

对于我们的理论任务,filterAndRemove也会影响原始的lastFactorials。

票数 2
EN

Stack Overflow用户

发布于 2012-08-20 16:31:19

从基础知识中猜到的答案是:如果你计划修改对象,并且你不想修改原始对象,那么你需要克隆它,在你的例子中,factors = lastFactors.clone();完成了,因为你不想修改lastFactors,而是克隆它,并将其发送到encodeIntoResponse(resp, factors);,其中可能包含修改它的代码。

票数 0
EN

Stack Overflow用户

发布于 2012-10-23 23:04:27

克隆数组的唯一原因是阻止(在本例中是并发的)数组元素的修改。然而,在这种情况下,如果没有其他方法修改lastFactors引用的数组,这看起来是不可能的,这在示例中是有意义的。存储在factorslastFactors中的数组都是由factor以完整的状态创建和返回的,并且它们的引用被分配到同步块中,这将导致它们被安全地发布。

除非encodeIntoResponse修改其factors参数的元素,否则在我看来,对clone的调用是不必要的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12034370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档