【发布时间】:2017-08-09 19:57:18
【问题描述】:
我希望对下面的代码是否完全线程安全并且不会泄漏“this”引用提供一些意见?我要做的基本上是使用 ExecutorService 在后台线程中引导/初始化另一个服务。
我只是有点担心,因为我从某个地方读到从构造函数启动线程是不好的做法,因为它会在类完全构造之前泄漏“this”引用。
public class MyService {
private final ExecutorService executorService;
private volatile AnotherService anotherService;
private volatile boolean isReady = false;
public MyService(final ExecutorService executorService) {
this.executorService = executorService;
start();
}
private void start() {
executorService.submit(new Runnable() {
@Override
public void run() {
try {
anotherService = init();
isReady = true;
} catch (Exception e) {
// do nothing, just retry later
}
}
});
}
private AnotherService init() {
// some code to initialize
return AnotherServiceBootstrap.getInstance().bootstrap();
}
// some other methods in class
}
非常感谢!
【问题讨论】:
-
您是否担心您可能会同时在两个线程中创建 MyService 的两个实例,而其中一个或两个实例最终可能会使用来自错误线程的 executorService?
-
我认为这种事情过于复杂和不必要。你知道你会打电话给那个服务吗?然后在您创建的对象的每个实例中创建或注入服务引用。这一切有什么好处?
-
您应该使用
AtomicBoolean而不是volatile boolean在这里解释stackoverflow.com/a/3787435/6138873 -
@PaulHicks 不,这不是这里关心的问题,关心的是是否存在将未完全初始化的 MyService 对象的“this”引用泄漏到另一个线程的情况
-
您应该与其他服务交谈。他们不应该设计难以使用的东西。世界正朝着 REST 微服务的方向发展。它们应该 100% 准备好使用。如果您不得不担心“引导”,那么他们做错了。
标签: java multithreading concurrency thread-safety