spring batch compositeitemprocessor multithread partitioner mezcla datos

Hola a todos los del foro de java , alguno ha manejado Spring Batch , ya que tengo una aplicacion de batch que estoy usando particiones y CompositeItemProcessor, en un ambiente concurrente , solo que al retornar el resultado a la lista CopyOnWriteArrayList me llena la lista con los datos de otro thread , mezclandose la informacion en cada thread que se supone es multithreading, y cada thread escribira esos datos en un archivo de salida , como cada thread tiene su rango de busqueda de informacion ejemplo: thread1 1-10, thread2 11-20,...y asi sucesivamente, espero puedan orientarme , no he encontrado donde esta el problema,a continuacion pongo parte de codigo , gracias .

public class CustomerItemProcessor implements ItemProcessor<beangenerico,CopyOnWriteArrayList<beanCustomer>>{

        private CustomerDAO customerDAO;
        private CopyOnWriteArrayList<beanCustomer> listbean;
       
       
        public CopyOnWriteArrayList<beanCustomer> process(beangenerico rangos) throws Exception {
               
                listbean = customerDAO.getAccAgentes(rangos);
               
                if(listbean != null) {
            return listbean;
        } else {
            return null;
        }
        }

        public void setCustomerDAO(CustomerDAO customerDAO) {
                this.customerDAO = customerDAO;
        }

}

La configuracion de mi xml de spring batch es esta:

<batch:job id="partitionJob" xmlns="http://www.springframework.org/schema/batch">
    <batch:step id="masterStep">
      <batch:partition step="slave" partitioner="rangePartitioner">
            <batch:handler grid-size="10" task-executor="taskExecutor"/>
      </batch:partition>
    </batch:step>
</batch:job>

<!-- each thread will run this job, with different stepExecutionContext values. -->
<batch:step id="slave" xmlns="http://www.springframework.org/schema/batch">
    <batch:tasklet task-executor="taskExecutor" throttle-limit="1">
        <batch:chunk reader="beaniniendreader" writer="tempRecordsWriter"  processor="completeItemProcessor" commit-interval="1" />
    </batch:tasklet>
</batch:step>

<bean id="taskExecutor"  class="org.springframework.core.task.SimpleAsyncTaskExecutor" />

<bean id="rangePartitioner" class="my.package.springbatch.RangePartitioner" />  
<bean id="beaniniendreader" class="my.package.springbatch.FormiikReader" scope="step"></bean>

<bean id="beanprocessor" class="my.package.springbatch.FormiikProcessor" scope="step">
       <property name="accountExecutiveDao" ref="accountExecutiveDao"/>
</bean>

<bean id="beanprocessor2" class="my.package.springbatch.CustomerItemProcessor" scope="step">
    <property name="customerDAO" ref="customerAccDao"/>
</bean>

<bean id="completeItemProcessor"  class="org.springframework.batch.item.support.CompositeItemProcessor">
     <property name="delegates">
        <list>
                <ref bean="beanprocessor2"/>
                <ref bean="accItemprocessor"/>
                <ref bean="beanaccDataItem"/>
        </list>
    </property>
</bean>

<bean id="tempRecordsWriter" class="my.package.springbatch.ListDelegateWriter" scope="step">
       <property name="delegate" ref="flatFileItemWriterPartition"/>
</bean>

<!-- csv file writer -->
<bean id="flatFileItemWriterPartition" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step" >
      <property name="resource" value="file:csv/outputs/users.processed#{stepExecutionContext[fromId]}-#{stepExecutionContext[toId]}.csv" />
         <property name="appendAllowed" value="false" />
         <property name="lineAggregator">
         <bean  class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
               <property name="delimiter" value="," />
               <property name="fieldExtractor">
               <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                     <property name="names" value="cuenta, name, purchasedPackage" />    
               </bean>
           </property>
        </bean>
    </property>
</bean>

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Nopalin

Nunca he utilizado spring

Nunca he utilizado spring batch asi que no puedo opinarte sobre como funciona. Lo que si puedo comentar es que ninguna variable en java es thread safe. Si al mismo dato que representa la variable deben accesar diferentes threads, lo mas recomendable es realizar el trabajo sobre esta variable usando synchronized (si no tambien pudieras encontrarte race conditions), si es la misma variable pero los datos son particulares de cada thread, entonces la variable la debes definir en un ThreadLocal.

uso de threadLocal en lugar de synchronized

Hola a todos , gracias @Nopalin por lo del threadlocal, se lo coloque ahora en el codigo ya no mezclo informacion y funciono, aqui coloco como ejemplo por si alguno le sirve o si acaso alguna otra sugerencia

public class CustomerItemProcessor implements ItemProcessor<beangenerico,ThreadLocal<CopyOnWriteArrayList<beanCustomer>>> {

        private CustomerDAO customerDAO;
        private ThreadLocal<CopyOnWriteArrayList<beanCustomer>> listbean = new ThreadLocal<CopyOnWriteArrayList<beanCustomer>>();      
       
        public ThreadLocal<CopyOnWriteArrayList<beanCustomer>> process(beangenerico rangos) throws Exception {
                       
                listbean.set(new CopyOnWriteArrayList<beanCustomer>());
                listbean = customerDAO.getAccAgentes(rangos);
               
                if(listbean != null) {
                   
                    return listbean;
                } else {
                    return null;
                }

        }

        public void setCustomerDAO(CustomerDAO customerDAO) {
                this.customerDAO = customerDAO;
        }
       
}