JavaBean 在其构造过程中可能处于不一致的状态。
我无法理解这一点,如果在方法中构造对象,那将如何不一致,如果必须发生异常,也可能在构造函数中发生。这与线程有什么关系?
JavaBean 在其构造过程中可能处于不一致的状态。
我无法理解这一点,如果在方法中构造对象,那将如何不一致,如果必须发生异常,也可能在构造函数中发生。这与线程有什么关系?
书中介绍了以下 bean:
NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);
其中,servingSize
and servings
set by setServingSize(int)
andsetServings(int)
是营养成分的基础——至少在书中是这样。
但如果你只是打电话:
NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setCalories(100);
那么该servings
字段将不会被设置。因此,生成的实例现在处于无效状态。
因此,如果您调用一个需要有效实例的方法,healthRiskCalculator.calculateHealthRisk(NutritionFacts facts)
那么您将在对象内或在healthRiskCalculator
.
因此,现在您可以在调用时检查对健康的损害,calculateHealthRisk()
但可能有许多方法读取或使用对象实例。此外,您可能还为其他产品创建了许多无效实例。换句话说,这不是快速失败。
因此,没有使用 bean 创建构造对象的故障安全方法。这不是线程特有的,您可以在单个线程中创建无效的 bean 实例。
想象一个线程模型,它ThreadUtils.doFoo(FooBean fb)
会在哪里产生一个可以与fb
. fb
可以像传递给该线程以定义其计算的参数一样简单。现在,采用以下构造函数:
public FooBean(int i, int j, int k, int l, int port){
ThreadUtils.doFoo(this);
someListField = Arrays.asList(i, j, k, l);
this.port = port;
}
这会导致this
从构造函数中泄漏。如果出于某种虚假原因,生成的线程在列表被正确实例化和分配之前起作用,那么您将有一个线程在this
. 例如,如果port
新线程使用新线程侦听套接字并被this
泄露,则套接字可能会侦听端口 0(数字字段的默认值),而不是端口port
。
事实上,如果构造函数中的异常this
被泄漏并从其他地方获得可访问的强引用,则可能会成为问题。
但是,以下构造函数是安全的:
public FooBean(int i, int j, int k, int l, int port){
someListField = Arrays.asList(i, j, k, l);
this.port = port;
ThreadUtils.doFoo(this);
}
这是因为在 Java 内存模型中,字段甚至在线程生成之前就已存储。