Rik*_*aaf 6 java multithreading constructor
我有一种情况,我总是需要运行一些依赖于对象本身的代码
public abstract class A{
public A(X x){
//init A stuff
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
}
}
public class B extends A{
public B(X x){
super(x);
//init B stuff
}
}
public class C extends A{
public C(X x){
super(x);
//init C stuff
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
}
}
public class SomeClass{
private X someX;
public A somefunc(boolean b){
if(b){
return new B(someX);
}else{
return new C(someX);
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题如下.在这个例子中,我this在构造函数中使用.如果另一个线程试图通过someX.getAList访问该对象,则可能导致该线程在构造函数结束之前访问该对象.
你可以使它通过somefunc将对象添加到AList中
public class SomeClass{
private X someX;
public A somefunc(boolean b){
A a;
if(b){
a = new B(someX);
someX.getAList("stuff").add(a);
someX.getAList("otherstuff").add(a);
}else{
a = new C(someX);
someX.getAList("stuff").add(a);
someX.getAList("morestuff").add(a);
}
return a;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是B和C也可以在别处实例化,并且每次创建B或C时都需要以指定的方式添加它们.我不希望将对象添加到AList是用户的责任,而是类的责任.我也不希望用户必须调用为它们执行此操作的init函数.另一方面,我不想要任何并发问题.
有没有一种方法或模式可以实现这一点?
Golang有类似defer的东西,它允许你在函数/ method/constructor完成后运行一段代码.
为super和subclass创建一个Factory-Method,并使构造函数成为私有,强制每个想要实例的人使用工厂方法.工厂方法是返回完全构造的实例的方法.一旦实例完全构造(在工厂方法中调用构造函数之后)将实例添加到列表中,这样就没有线程可以获得不完整/未完成的实例.
Factory-Method的要点是严格地将所有初始化代码与任何非初始化代码隔离,以避免访问和暴露未初始化的字段.它还可以作为用户的选择器,自动返回合适的(子)类型,而无需指定.(有趣的设计模式)
abstract class A{
protected A(){
//constructor code goes here
}
public void afterFinalisation(final X x) {
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
}
}
class B extends A{
protected B(){
super();
//constructor code goes here
}
public static B create(final X x) {
final B returnValue = new B();
returnValue.afterFinalisation(x);
return returnValue;
}
}
class C extends A{
protected C(){
super();
//constructor code goes here
}
@Override
public void afterFinalisation(final X x) {
super.afterFinalisation(x);
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
}
public static C create(final X x) {
final C returnValue = new C();
returnValue.afterFinalisation(x);
return returnValue;
}
}
class SomeClass{
private final X someX = new X();
public A somefunc(final boolean b){
if(b){
return B.create(this.someX);
}else{
return C.create(this.someX);
}
}
}
Run Code Online (Sandbox Code Playgroud)
构造函数代码的功劳归功于我的回答的coolcats迭代,我试图避免将代码放入受保护的构造函数中,而是使用init()方法,这需要一个非常不优雅的最终字段的解决方法.
| 归档时间: |
|
| 查看次数: |
1282 次 |
| 最近记录: |