尝试将resource作为类成员



我尝试使用类成员作为try块中的资源(因为该资源需要在try块后调用close(((:

class Manager {
MyResource m_myResource;
...
void doTraining() {
m_myResource = createMyResource();
try(m_myResource) {
...
}
}

}

但会有人抱怨说m_myResource不是有效的决赛。为什么?我认为m_myResource在初始化后没有改变。无论如何,不知道如何解决这个问题。我能想到的一种方法是:

class Manager {
MyResource m_myResource;
...
void doTraining() {
MyResource newResource = createMyResource();
m_myResource = newResource;
try(m_myResource) {
...
}
}
}

但我不确定将本地资源分配给类成员是否会引起任何问题?

应避免维护用于存储寿命有限的对象的字段。但如果你真的需要它,代码应该看起来像
class Manager {
MyResource m_myResource;
...
void doTraining() {
try(MyResource newResource = createMyResource()) {
m_myResource = newResource;
...
}
finally {
m_myResource = null;
}
}
}

因此,当doTraining()try()块中没有正在进行的操作时,字段总是null

很明显,doTraining的这个实现是不可重入的;无论是通过多个线程还是通过递归调用,都不能有对该方法的重叠调用。

如前所述,不建议这样做。但有时,通过操作中使用的所有API层传递资源是不切实际的。这种情况的存在已经被认识到,并且有一个计划的通用解决方案ExtentLocal

有了这个,未来的版本将看起来像

class Manager {
final static ExtentLocal<MyResource> MY_RESSOURCE = new ExtentLocal<>();
...
void doTraining() {        
try(MyResource newResource = createMyResource()) {
ExtentLocal.where(MY_RESSOURCE, newResource )
.run(() -> {/* code indirectly invoking foo */});
...
}
}
void foo() {
var resource = MY_RESSOURCE.get();
// use resource
}
}

请注意,这不会使传递本地有效资源的实例发生变化。所以这里,doTraining()是可重入的。

但是,这是在未来的某个地方…

相关内容

  • 没有找到相关文章

最新更新