我正在使用Mule组件处理Salesforce查询中的记录。我写了一个Mule组件来使用ConsumerIterator来批量聚合100个记录。但是,我没有得到所有记录。我包含了一个简单的计数来计算所有记录,我使用AtomicInteger来计算传递给方法handOff的总值。我也打印出线程名称,因为我不认为这是一个线程问题。我正在使用同步流程。我正在使用石英组件,但我已将其配置为仅使用1个接收器线程。这应该确保我使用相同的线程进行处理。我已经包含了代码。线程名称始终相同。 ConsumerIterator报告7348条记录,“count”变量也报告7348.但AtomicInteger计数器报告7276条记录,即72条记录短。 请有人看看这个,告诉我为什么以及如何解决它?
public class Aggregator implements Callable {
private Logger LOG=LoggerFactory.getLogger(Aggregator.class);
private AtomicInteger at=new AtomicInteger();
public Aggregator() {
}
@Override
public Object onCall(MuleEventContext context) throws Exception {
Object obj=context.getMessage().getPayload();
ConsumerIterator<HashMap<String,Object>> iterator=
(ConsumerIterator<HashMap<String,Object>>)obj;
List<HashMap<String,Object>> l=new ArrayList<>();
LOG.info("Iterator has "+iterator.size()+" elements!");
int count=0;
while(iterator.hasNext()){
count+=1;
Object payload=iterator.next();
LOG.info("Processing Next:: => "+payload);
if(l.size()<100){
l.add((HashMap<String,Object>)payload);
}else {
LOG.info("Just handing off to write :: => Size is "+l.size());
handoff(l);
l=new ArrayList<HashMap<String,Object>>();
}
if(!iterator.hasNext() && l.size()<=100){
LOG.info("Now it's less than 100, and it also has no more
elements, so handing off, or they will be lost!! : =>
"+l.size()+"
elements");
handoff(l);
l=new ArrayList<HashMap<String,Object>>();
}
}
LOG.info("Done with List !!!!");
LOG.info("Simple count is "+count);
LOG.info("Number of elements in counter is "+at.get());
LOG.info("Thread Name is "+Thread.currentThread());
return NullPayload.getInstance();
}
private void handoff(List<HashMap<String, Object>> l) {
at.getAndAdd(l.size());
LOG.info("handoff:: Thread Name is "+Thread.currentThread());
LOG.info("Number of elements in List is "+l.size());
for(HashMap<String, Object> m : l){
Object obj=m.get("CreatedBy") ;
if(obj!=null){
LOG.info("OBJ====="+obj);
LOG.info(obj.getClass().getCanonicalName());
}
}
}
答案 0 :(得分:0)
你有没有累 CopyOnWriteArrayList (List接口的线程安全实现可能有帮助) 尝试替换
List<HashMap<String,Object>> l=new ArrayList<>();
与
List<HashMap<String,Object>> l=new CopyOnWriteArrayList<HashMap<String,Object>>();
并且
l=new ArrayList<HashMap<String,Object>>();
与
l=new CopyOnWriteArrayList<HashMap<String,Object>>();
答案 1 :(得分:0)
解决问题:正如我所说,这不是一个线程问题。这是收集数据的逻辑中的一个微妙错误。当列表<100时,代码分支到切换方法,然后创建新列表。但是,interator.next()中的元素会发生什么?它需要添加到新列表中。所以修正是在else分支中:
if(l.size()<100){
l.add((HashMap<String,Object>)payload);
}else {
LOG.info("Just handing off to write :: => Size is "+l.size());
handoff(l);
l=new ArrayList<HashMap<String,Object>>();
l.add((HashMap<String,Object>)payload)
}