Camel Splitter并行处理数组列表 - 并发访问问题

时间:2014-11-05 22:23:28

标签: java multithreading arraylist apache-camel splitter

使用Camel拆分ArrayList并并行处理每个项目最多10个线程。 以下是配置。 线程池配置文件设置为最大线程数= 10。

<camel:route id="ReportsRoute">
        <camel:from uri="direct:processReportsChannel" />
        <camel:to uri="bean:reportRepository?method=getPendingTransactions" />
        <camel:split parallelProcessing="true" executorServiceRef="ReportThreadPoolProfile">
            <camel:simple>${body}</camel:simple>
            <camel:doTry>
                <camel:to uri="direct:processReportChannel" />
                <camel:doCatch>
                    <camel:exception>java.lang.Exception</camel:exception>
                    <camel:handled>
                        <camel:constant>true</camel:constant>
                    </camel:handled>                        
                    <camel:to uri="bean:ReportRepository?method=markAsFailed"/>
                    <camel:wireTap uri="direct:loggingAndNotificationChannel" />
                </camel:doCatch>
            </camel:doTry>
        </camel:split>
    </camel:route>  

bean:reportRepository?method=getPendingTransactions获取ArrayList并传递给Splitter。

processReportChannel是处理项目的处理器。

问题: 作业启动时它会启动10个线程,但有些线程正在拾取相同的项目。例如,如果我在ArrayList,thread_no_1和thread_no_2中有item_no_1到10,或者有时候更多的线程正在拾取,请说item_no_2。是因为Array List不是线程安全的,而且Splitter没有管理它吗?

我不是这方面的专家,需要帮助指出问题所在。

1 个答案:

答案 0 :(得分:0)

我使用以下(更简单的)设置进行了测试:

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="ReportsRoute">
        <from uri="direct:start" />
         <!-- By default a pool size of 10 is used. -->
        <split parallelProcessing="true">
            <simple>${body}</simple>
            <to uri="direct:sub" />
        </split>
    </route>  
    <route>
        <from uri="direct:sub"/>
        <log message="Processing item ${body}" />
    </route>
</camelContext>

测试:

 List<Object> list = new ArrayList<>();
 for (int i = 0; i < 1000; i++) {
    list.add("And we go and go: " + (i + 1));
 }
 template.sendBody("direct:start", list);

使用此设置,没有任何条目被处理两次。因此,处理器中必定存在导致问题的内容,即同一个列表项由多个线程拾取。