这是我的代码..
@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))
return null;
else
return Arrays.copyOf(lastFactors, lastFactors.length);
}
}
@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);
if(factors==null){ // ---> line 1
factors=factor(i); // --> line 2
cache=new OneValueCached(i, factors);
}
encodeIntoResponse(resp,factors);
}
}
为什么class VolatileCachedFactorizer 是 Book 的主题但是我的观点是......
的 1。 @第1行如果2个帖子同时在该点thread
检查条件,并且发现 factor = null 和第2 thread
也检查相同的条件第一次thread
暂停在第二行后的同一时间,发现 factor = null
并且两者都将创建新的OneValueCached
对象然后这个代码是如何线程安全的..根据书,这是线程安全..
感谢的
答案 0 :(得分:3)
它是线程安全的,因为lastNumber
和lastFactors
之间永远不会出现不一致,这可能导致不正确的因子分解。它不能保证最小量的因子分配将发生:OneValueCached
可以多次创建,但仍然是线程安全的。
答案 1 :(得分:1)
这里没有定义“线程安全”的确切概念。对于这个代码是线程安全的,你期望发生什么/不发生什么?
Cache
时期望单个创建service
对象,则它不是线程安全的。同样,如果没有为这种情况定义线程安全行为,我们无法确切地说出来。
答案 2 :(得分:0)
此代码是线程安全的。但我不认为构造函数中的Array.copyOf()
是必要的。
答案 3 :(得分:0)
虽然这是一年多前提出的问题,但我还是想解释一下。 实际上,这段代码是从“Java Concurrency in Practice”,第40页中采用的。作者声称VolatileCachedFactorizer是一个线程安全的servlet,因为servlet程序本身是由用户同时调用的。所以作者意味着如果viariable - OneValueCached缓存可以由线程一致地读取和写入,这意味着不会导致诸如lastNumber和lastFactors之类的情况不匹配,那么它将是线程安全的。我很困惑的是,该书仅声称Arrays.copyOf()函数使用它,它将是线程安全的。但为什么?为什么需要Arrays.copyOf()?
答案 4 :(得分:0)
Qisen,回答你的问题,需要使用Arrays.copyOf(),因为否则OneValueCache不会是不可变的。如果在构造OneValueCache时没有复制因子,那么您将允许对该数组的引用(直到该点为正在运行的线程的本地)进行转义。