Java 等待所有线程在Spring集成中完成

Java 等待所有线程在Spring集成中完成,java,multithreading,spring,spring-integration,Java,Multithreading,Spring,Spring Integration,我有一个自我执行的jar程序,它严重依赖于Spring集成。我遇到的问题是,程序在其他SpringBean完全完成之前终止 下面是我正在使用的代码的简化版本,如果需要,我可以提供更多的代码/配置。入口点是main()方法,它引导Spring并启动导入过程: public static void main(String[] args) { ctx = new ClassPathXmlApplicationContext("flow.xml"); DataImporter impor

我有一个自我执行的jar程序,它严重依赖于Spring集成。我遇到的问题是,程序在其他SpringBean完全完成之前终止

下面是我正在使用的代码的简化版本,如果需要,我可以提供更多的代码/配置。入口点是main()方法,它引导Spring并启动导入过程:

public static void main(String[] args) {
    ctx = new ClassPathXmlApplicationContext("flow.xml");
    DataImporter importer = (DataImporter)ctx.getBean("MyImporterBean");
    try {
        importer.startImport();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        ctx.close();
    }
}
DataImporter包含一个向Spring集成网关发送消息的简单循环。这为流提供了一种主动的“推送”方法,而不是常见的数据轮询方法。这就是我的问题所在:

public void startImport() throws Exception {
    for (Item item : items) {
        gatewayBean.publish(item);
        Thread.sleep(200); // Yield period
    }
}
为完整起见,流XML如下所示:

<gateway default-request-channel="inChannel" service-interface="GatewayBean" />

<splitter input-channel="inChannel" output-channel="splitChannel" />

<payload-type-router input-channel="splitChannel">
    <mapping type="Item" channel="itemChannel" />
    <mapping type="SomeOtherItem" channel="anotherChannel" />
</payload-type-router>

<outbound-channel-adapter channel="itemChannel" ref="DAOBean" method="persist" />

流启动并有效地处理项,但一旦startImport()循环完成,主线程就会终止并立即中断所有Spring集成线程。这将导致一个竞争条件,当程序终止时,最后(n)个项目没有被完全处理

我有一个想法,就是维护我正在处理的项目的引用计数,但这被证明是相当复杂的,因为流经常将消息拆分/路由到多个服务激活器,这意味着很难确定每个项目是否已“完成”

我想我需要的是某种方法来检查是否没有Springbean仍在执行,或者标记发送到网关的所有项目在终止之前都已被完全处理


我的问题是,我该如何做这两项工作,或者有没有更好的方法来解决我的问题呢?

如果你能得到一个
项来确定它是否仍然需要(processingFinished()或在后端阶段执行的类似操作),您可以在中央机构注册所有
项目
s,该机构跟踪未完成
项目
s的数量,并有效地确定终止条件

如果这种方法可行,您甚至可以考虑将项目打包到
FutureTask
-对象中,或者使用
java.util.concurrent
中的类似概念

编辑:第二个想法:


你有没有想过让频道更智能化?发送方在不再发送任何数据时关闭通道。在这种情况下,工作bean不必是deamon线程,但可以根据一个封闭的空输入通道确定它们的终止标准。

这里不使用请求-响应模式


出站通道适配器是一种“即发即忘”操作,如果要等待响应,应使用一个将等待响应的出站网关,并将响应连接到原始网关,然后在java Send和Receive中不仅仅发布。

其中有一些好主意。但是,在我的项目中,“Item”类过于通用(模型层的一部分),无法添加导入逻辑。我可能会想办法对消息头执行类似的操作。FutureTask等人会很好,但我正在努力寻找一种方法来利用并发框架解决我的具体问题……这确实是我的问题。我将流修改为使用而不是,并将结果连接到异步网关。我现在可以使用Future.isDone()等待完成。谢谢你的帮助!