gpt4 book ai didi

java - 代码是线程安全的吗?

转载 作者:行者123 更新时间:2023-11-30 08:07:14 24 4
gpt4 key购买 nike

我在 StackOverflow 上查看了一些关于这个片段的问题,但没有一个提到我发现的问题。

代码如下:

@immutable // This is not a standard annotation .Only for Showing that behavior of Class 
class OneValueCached{
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCached(BigInteger i,BigInteger[] factors){
lastNumber=i;
lastFactors=Arrays.copyOf(factors, factors.length);
}

public BigInteger[] getFactors(BigInteger i){
if(lastNumber==null || !lastNumber.equals(i)) // ---> line 2
return null;
else
return Arrays.copyOf(lastFactors, lastFactors.length); // ---> line 3
}
}

@threadSafe // This is not a standard annotation .Only for Showing that behavior of Class
public class VolatileCachedFactorizer implements Servlet{
private volatile OneValueCached cache=new OneValueCached(null, null);

public void service(ServletRequest req, ServletResponce resp){
BigInteger i= extractFromRequest(req);
BigInteger[] factors=cache.getFactors(i); // ---> line 1
if(factors==null){
factors=factor(i);
cache=new OneValueCached(i, factors); // ---> line 4
}

encodeIntoResponse(resp,factors);
}
}

想象一下,

线程A来到第1行,调用cache.getFators(BigInteger i),来到第2行,条件语句返回false

然后线程B来到第1行,同样调用了cache.getFators(BigInteger i),到了第2行,条件语句返回true。所以线程 B 继续,并来到第 4 行,将变量 cache 更改为一个新变量。

线程 A 继续,到达第 3 行,返回错误结果!

那怎么了?这段代码是线程安全的吗? (根据 Java Concurrency in Practice 一书,是的,它是线程安全的)

更新:

我在想,当线程 B 将 cache 的值更改为新值时,线程可能仍会返回上一个对象的 lastFactors 的副本。我说得对吗?

最佳答案

是的,这段代码是线程安全的。

因为 OneValueCached 是不可变的,它的实例永远不会返回错误的结果,假设它是用正确的值构造的。它要么返回正确的结果,要么返回 null

当缓存值改变时,cache 变量自动改变,因为它是volatile。可能是在某个时间使用了两个 OneValueCached 实例:调用一个实例的方法,然后执行线程更改,创建一个新实例并更改 cache 引用指向一个新实例,但它不会影响其他线程和旧实例,直到方法调用返回(执行方法中的this变量保持它还活着)。

此外,在 cache 中存储不必要的实例并没有特别的效率损失,因为无论如何都需要创建实例,而实际上将引用存储在 cache 中是无关紧要的从性能的角度。实现缓存的不同方式(例如能够存储多个值)可以进一步提高性能,但这样做仍然不会比根本不缓存更糟(内存使用模式的差异无关紧要),即使在最坏的情况下(从未使用过的缓存值)。

关于java - 代码是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33844905/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com