缺少来自Mule ConsumerIterator

时间:2017-12-29 20:05:03

标签: java collections mule

我正在使用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());
             }
          }

    }

2 个答案:

答案 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)
    }