【发布时间】:2014-11-15 17:21:04
【问题描述】:
我有一个 Manager 类,它封装了一个(相当)低级设施(例如数据库)并用作 Worker 实例的工厂,它
- 使用
Manager的底层设施(数据库) - 从每个实例引用
Manager - 同时使用
- 可以启动引用数据库的异步任务(在一些分离的线程中)。
Manager 还有一个shutdown() 方法可以关闭数据库连接。为了确保在任何worker 启动任何正在运行的线程时连接保持活动状态(即在仍有工作人员使用它之前不要关闭数据库连接),我目前有这样的事情:
Manager mgr = new Manager(database);
Worker worker = mgr.newWorker(arg0, arg1, arg2);
worker.runHeavyComputation();
runHeavyComputation 的定义如下:
void runHeavyComputation() {
executor.execute(() -> {
myManager.tellTaskLaunched();
doSomethingWithDatabase();
myManager.tellTaskFinished();
});
}
Manager#tellTaskLaunched() 和 Manager#tellTaskLaunched() 的定义如下:
void tellTaskLaunched() {
taskCounter.incrementAndGet();
}
void tellTaskFinished() {
taskCounter.decrementAndGet();
}
而Manager#shutdown() 看起来像这样:
void shutdown() {
while (taskCounter.get() > 0) {}
databaseConnection.close();
database.shutdown()
}
我知道对于这样一个简单的问题,这是一个有点冗长的介绍,但由于我几乎在我读过的每一本书或每篇文章中都遇到过反忙等待的陈述,我突然想到可能有一些替代方案我在这里提供的简单解决方案,所以我想听听您的意见。
请注意,由于shutdown() 可能会在每个应用程序生命周期(或他们所谓的单个长期运行)中调用一次,因此这并不是真正的性能问题。但是,如果出现更好的情况,我仍然会更改它。
附:另请注意,虽然我说的是“您的意见”,但这并不是一个真正的基于意见的问题 :)
【问题讨论】:
-
您可以检查是否在 tellTaskFinished() 中调用了关机,如果是并且计数器为 0 - 关闭连接。
-
@BobTheBuilder,您认为可以将处理连接的逻辑与现在
tellTaskFinished()内部发生的简单任务记帐相结合吗? -
对我来说看起来不错。这就像触发“任务结束”事件,如果需要,管理器可以使用它来监视和关闭连接。
标签: java multithreading performance thread-synchronization