不可变对象

ningbohezhijun 2014-09-16 11:44:18
最近在看《Java 7并发编程实战手册》,遇到了个问题,希望大家帮忙。

问题是关于:不可变对象与线程安全,代码如下


@Immutable
class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;

public OneValueCache(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);
}
}

可以看到OneValueCache是不可变对象。


@ThreadSafe
public class VolatileCachedFactorizer 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);
//由于cache为volatile,所以最新值立即能让其它线程可见
cache = new OneValueCache(i, factors);
}
encodeIntoResponse(resp, factors);
}
}

但是我又该如何理解VolatileCachedFactorizer类是线程安全的。总感觉理不清,也不知道去理清这个问题的重点是哪里。
书上是这么解释的(我没有理解):
与cache相关的操作不会相互干扰,因为OneValueCache是不可变的,并且在每条相应的代码路径中只会访问它一次。通过使用包含多个状态变量的容器对象来维持不变性条件,并使用一个volatile类型的引用来确保可见性,使得VolatileCachedFactorizer在没有显示地使用锁的情况下仍然是线程安全的。

请点拨我一下,谢谢!
...全文
132 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangweiah 2015-04-15
  • 打赏
  • 举报
回复
我的理解如下, 保证VolatileCachedFactorizer的线程安全无非是要做到两点: 1.cache 指向对象的引用对其他线程可见或是不可变。 2.cache 指向对象里面所有的域对其他线程是可见或是不可变。 你看,cache用volatile修饰可以保证引用对其他线程可见,即满足了第1条。 而且OneValueCache 里面域都用final修饰,即可以保证域是不可变的,既满足了第2条。
内容概要:本文详细介绍了利用Simulink进行压器开路试验的电路连接配置与仿真实现方法,重点在于通过仿真手段还原实际电力系统中压器在空载条件下的电气特性,从而深入理解其工作原理与性能表现。文章作为电力系统仿真系列研究的一部分,系统阐述了从电路模型搭建、参数设定、仿真运行到结果分析的完整流程,突出展示了MATLAB/Simulink在电力设备建模与教学科研中的强大功能与应用价值。; 适合人群:具备电力系统基础知识,熟悉MATLAB/Simulink仿真环境,从事电气工程、自动化及相关领域的研发人员,以及高年级本科生和研究生。; 使用场景及目标:①掌握压器开路试验的基本原理与Simulink仿真建模的具体步骤;②通过仿真实验深入理解空载电流、铁芯损耗及励磁特性等关键参数的物理意义;③为后续开展压器短路试验、暂态过程分析以及其他电力设备的仿真研究奠定理论与实践基础。; 阅读建议:建议结合Simulink软件动手实践,逐步构建并调试电路模型,重点关注各元件参数的设置方法与测量模块的应用技巧,同时推荐参考文中提及的其他相关仿真案例进行拓展学习,以全面提升对电力系统仿真实践的整体认知与操作能力。

67,536

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧