Ho una classe di entità
package org.demo.stack;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class ValueHolder{
@Id
private Long id;
@Column
private Long value;
/* getters and setters... */
}
un relativo repository JPA di primavera
package org.demo.stack;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ValueHolderRepository extends JpaRepository<ValueHolder, Long>
{
}
e una classe che funge da accumulatore di alcuni tipi di valori, utilizzando il repository (Si noti che questa è una versione semplificata di un vero programma)
package org.demo.stack;
import java.util.List;
public class ValueAccumulator{
private ValueHolderRepository repository;
private Long accumulator;
public ValueAccumulator(ValueHolderRepository repository){
this.repository = repository;
accumulator = 0L;
}
public Long sumOverResults(){
accumulator = 0L;
List<ValueHolder> holders = repository.findAll();
for(ValueHolder holder : holders){
accumulator = accumulator + holder.getValue();
}
return accumulator;
}
}
ValueAccumulator non è chiaramente thread-safe. Se condivido la stessa istanza su diversi thread e sumOverResults
è chiamato contemporaneamente, il
variabile d'istanza accumulator
avrà un valore non prevedibile.
Ho anche un adattatore che assomiglia a ConcurrentValueAccumulator
:
package org.demo.stack;
public class ConcurrentValueAccumulator{
private ValueHolderRepository repository;
public Long sumOverResults(){
ValueAccumulator oneShotAccumulator = new ValueAccumulator(repository);
return oneShotAccumulator.sumOverResults();
}
}
Ora ogni chiamata a sumOverResults
utilizza la propria istanza di ValueAccumulator
, quindi nessun dato
sono condivisi tra thread.
Partendo dal presupposto che nessun ValueEntity
s viene inserito o aggiornato durante il processo,
posso essere sicuro al 100% che ConcurrentValueAccumulator
sia thread-safe?