Spring batch jsr 352 如何防止分区作业使线程保持活动状态从而阻止进程结束

Spring batch jsr 352 how to prevent partitioned job from leaving thread alive which prevent process from ending

让我解释一下我的应用程序是如何设置的。首先,我有一个独立的命令行启动应用程序,它 运行s 是一个主应用程序,它依次调用传递适当参数的作业操作员的启动。我知道 start 是一个异步调用,一旦我调用 start 除非我阻止它在我的 main 中如何死掉。

我 运行 遇到的问题是,当我 运行 一个分区作业时,它似乎使一些线程处于活动状态,从而阻止了整个处理结束。当我 运行 一个非分区作业时,一旦作业完成,进程就会正常结束。

这是正常的 and/or 预期行为吗?有没有办法告诉分区线程死掉。似乎分区线程在作业完成后被阻塞等待某些东西,但它们不应该这样?

我知道我可以在 main 中监视批处理状态并可能结束它,但正如我在另一个问题中所述,这给数据库增加了大量的喋喋不休,并不理想。

我的工作规范示例

<job id="partitionTest" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="onlyStep">
    <partition>
        <plan partitions="2">
            <properties partition="0">
                <property name="partitionNumber" value="1"></property>
            </properties>
            <properties partition="1">
                <property name="partitionNumber" value="2"></property>
            </properties>
        </plan>
    </partition>

    <chunk item-count="2">
        <reader id="reader" ref="DelimitedFlatFileReader">
            <properties>
                <!-- Reads in from file Test.csv -->
                <property name="fileNameAndPath" value="#{jobParameters['inputPath']}/CSVInput#{partitionPlan['partitionNumber']}.csv" />
                <property name="fieldNames" value="firstName, lastName, city" />
                <property name="fullyQualifiedTargetClass" value="com.test.transactionaltest.Member" />
            </properties>
        </reader>
        <processor ref="com.test.partitiontest.Processor" />
        <writer ref="FlatFileWriter" >
            <properties>
                <property name="appendOn" value="true"/>
                <property name="fileNameAndPath" value="#{jobParameters['outputPath']}/PartitionOutput.txt" />
                <property name="fullyQualifiedTargetClass" value="com.test.transactionaltest.Member" />
            </properties>
        </writer>
    </chunk>
</step>
</job>

编辑:

好的,阅读更多有关此问题的信息并查看 spring 批处理代码,至少在我看来 JsrPartitionHandler 中似乎存在错误。具体来说,handle 方法会在本地创建一个 ThreadPoolTask​​Executor,但该线程池永远不会被正确清理。应该在该方法 returns 之前调用 shutdown/destroy 以执行一些清理,否则线程将留在内存中并超出范围。

如果我在这里错了请纠正我,但这肯定是问题所在。

我打算尝试对其进行更改,看看效果如何。我会在完成一些测试后更新。

我已确认此问题是 spring 批处理核心库中的错误(我认为仍然是 atm)。

我在 spring 批处理 jira 站点上创建了一个 ticket。票证上有一个简单的附加 java 项目,可以确认我遇到的问题。如果其他人遇到问题,他们应该参考那张票。

我找到了一个临时解决方法,它只使用 wait/notify 方案,而且似乎一旦添加,池线程就会关闭。我将添加每个 classes/code 并尝试解释我所做的。

在 main thread/class 中,这是存在于 main 方法或从 main

调用的方法中的代码
        while(!ThreadNotifier.instance(this).getNotify()){
        try {
            synchronized(this){
                System.out.println("WAIT THREAD IS =======" + Thread.currentThread().getName());
                wait();
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

这是 ThreadNotifier class

public class ThreadNotifier {


private static ThreadNotifier tn = null;

private boolean notification = false;

private Object o;

private ThreadNotifier(Object o){
    this.o = o;

}

public static ThreadNotifier instance(Object o){

    if(tn == null){
        tn = new ThreadNotifier(o);
    }

    return tn;
}


public void setNotify(boolean value){
    notification = true;
    synchronized(o){
        System.out.println("NOTIFY THREAD IS =======" + Thread.currentThread().getName());
        o.notify();
    }
}

public boolean getNotify(){
    return notification;
}

}

最后这是我用来提供回通知的作业侦听器

public class PartitionWorkAround implements JobListener {

@Override
public void beforeJob() throws Exception {
    // TODO Auto-generated method stub

}

@Override
public void afterJob() throws Exception {

    ThreadNotifier.instance(null).setNotify(true);

}

}

在问题解决之前,这是我能想到的最好的办法。作为参考,我使用有关受保护块 here 的知识来找出执行此操作的方法。