gpt4 book ai didi

java - 安全停止线

转载 作者:行者123 更新时间:2023-12-03 12:59:03 27 4
gpt4 key购买 nike

我有一些课:

@Component
public MyClass {
private volatile boolean stopped = false;

public void verification() throws Exception {

Thread kpiAllThread = getKPIAllThread();

try {
for (int i = 0; i < poolSize; i++) {
execDispatcher.put(processExecutor.submit(getCheckValuesInKPIConsumerTask(workingQueue)));
}
kpiAllThread.start();
} finally {
waitFinished();
}
}

public void setStop(bolean stopped) {
this.stopped = stopped;
}

private Thread getKPIAllThread() {
return new Thread(() -> {
try {
LOG.debug("KPIAllThread started!");
dao.getKpiAll(workingQueue);
for (int i = 0; i < poolSize; i++) {
workingQueue.put(() -> true);
}
} catch (Exception ex) {
LOG.error("KPIAllThread exception: ", ex);
} finally {
LOG.error("KPIAllThread finished!");
}
});
}
}

此类启动生产者线程 getKPIAllThread。他从db获取数据,并放入 BlockingQueue

像这样的 getKpiAll方法:
public void getKpiAll(final BlockingQueue<KeyPropertyIndex> kpiData) throws Exception {
LOG.debug("Starting getKpiAll");
try (final Connection con = dataSource.getConnection();
final Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
stmt.setFetchSize(Integer.MIN_VALUE);

try (final ResultSet rs = stmt.executeQuery(sqlGetAllkpi)) {
while (rs.next()) {
kpiData.put(new KeyPropertyIndexData(rs.getLong(1), rs.getString(2)));
}
}
LOG.debug("Finished get getKpiAll");
} catch (Exception ex) {
throw ex;
}
}

还有一个 stopped变量,可以从外部设置为 true。这样做时如何安全地停止线程?这样就关闭了与数据库的所有连接,并且线程成功完成了吗?

最佳答案

停止线程的最干净最安全的规则是,在线程中运行的代码应定期检查条件(例如boolean shouldExit())。当代码检测到此条件为true时,应停止执行操作并终止。

在线程中运行的代码应相当频繁地检查这种情况,以使其能够做出较快的响应。根据经验,设置此条件后,线程应退出不到一秒钟的时间。该检查通常会在for循环中的某个地方看起来像if (shouldExit()) break,它会在池大小上进行迭代。但是,dao.getKpiAll(workingQueue)看起来可能很长,因此您可以在getKpiAll内放置更多检查。

进行此检查后,必须确保每当条件变为true时,您的代码便会干净退出。例如,您可以使用finally块关闭任何连接等。如果在getKpiAll期间发生这种情况,甚至没有必要继续使用for循环来处理项目等。

有时,这可能会变得更加棘手-例如,当线程正在等待网络操作时,您可能需要关闭网络套接字或类似的东西才能中断它。无论如何,请避免使用Thread.stop()Thread.interrupt()-请参阅文档,了解它们为何有问题。

如果执行这样的操作,则可以随时从线程外部设置条件以请求终止线程。您可以制作类似void requestExit()的东西,并在其中设置一个 boolean 变量。调用requestExit()后,您以适当的超时调用Thread.join()来等待线程开始其业务,检查条件并退出。再次,根据经验,将超时设置为线程的最长响应时间的3到10倍。

看来您已经有了用于此目的的setStopped(boolean stopped),但您没有进行检查。首先,我将删除参数stopped,因为将false传递给它没有意义。其次,您需要如上所述添加检查。您可能想使此变量对dao可见-请记住,将其公开为同步 boolean 方法比将其公开为 boolean 字段要好得多。

关于java - 安全停止线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52666086/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com