Quando se trata de operar um objeto entre threads, seja escrita e leitura posterior, existe a ocorrencia de tres situacoes distintas: processamento paralelo, geracao de referencias do objeto de origem e a atualizacao tardia da alteracao do objeto porque a JVM nao garante imediates nesta questao.Estas tres situacoes mencionadas, quando combinadas, terminam normalmente num problema de sincronismo que pode interferir em muito a integridade do processamento concorrente (nao paralelo apenas) de objetos e deixar qualquer programador ou projetista do campo em questao com bastante dor de cabeca costumeiramente.O problemaA bateria de classes a seguir compoem uma simulacao de um problema de atraso no sincronismo prejudicial para a operacao concorrente de objetos. O valor operado e outData do tipo ValueObject, pois a operacao final copiar os parametros de inData, tambem do tipo ValueObject, para outdata:A classe ValueObject e o objeto da operacaopublic class ValueObject { private long id; private String name; public ValueObject() { this.id = 0L; this.name = null; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("ValueObject [id="); builder.append(id); builder.append(", name="); builder.append(name); builder.append("]"); return builder.toString(); }}A classe AbstractExecutor implementa Runnable para apoiar a concorrenciapublic abstract class AbstractExecutor implements Runnable { private ValueObject inData; private ValueObject outData; abstract void execute(ValueObject inData, ValueObject outData); @Override public void run() { this.execute(inData, outData); this.setOutData(outData); } public ValueObject getInData() { return inData; } public void setInData(ValueObject inData) { this.inData = inData; } public ValueObject getOutData() { return outData; } public void setOutData(ValueObject outData) { this.outData = outData; }}A classe FinalExecutor herda AbstractExecutor para realizar a operacao concorrentepublic class FinalExecutor extends AbstractExecutor { @Override protected void execute(ValueObject inData, ValueObject outData) { outData.setId(inData.getId()); outData.setName(inData.getName()); }}A classe ThreadPoolExecution gera a execucao paralela com falha no sincronismo import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolExecution <E extends AbstractExecutor> { private static int executions; static { executions = 0; } private Class<E> clazz; private ExecutorService threadPool; public ThreadPoolExecution(Class<E> clazz) { this.clazz = clazz; this.threadPool = Executors.newFixedThreadPool(2); } public void execute(ValueObject inData, ValueObject outData) { try { E executor = (E) this.clazz.newInstance(); executor.setInData(inData); executor.setOutData(outData); executions++; threadPool.execute(executor); if (outData.getId() == 0L) { System.out.println(String.format("Nao alterado o objeto da execucao %d: %s", executions, outData.toString())); } else { System.out.println("ok"); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}A classe MainTest executa em serie, mas o resultado e o processamento paralelo porque tem como executor de FinalExecutor o ThreadPoolExecution public class MainTest { public static void main(String[] args) { ThreadPoolExecution<FinalExecutor> tpe = new ThreadPoolExecution<FinalExecutor>(FinalExecutor.class); for (long count = 1L; count <= 1000; count++) { ValueObject inData = new ValueObject(); ValueObject outData = new ValueObject(); inData.setId(count); inData.setName(String.format("Named %d", count)); tpe.execute(inData, outData); } } }Resultado com erroNao alterado o objeto da execucao 1: ValueObject [id=1, name=Named 1]Nao alterado o objeto da execucao 2: ValueObject [id=0, name=null]...Nao alterado o objeto da execucao 997: ValueObject [id=0, name=null]Nao alterado o objeto da execucao 998: ValueObject [id=0, name=null]Nao alterado o objeto da execucao 999: ValueObject