Fix possible IndexOutOfBoundsException due to concurrent access

This commit is contained in:
serso 2017-08-02 10:59:56 +02:00
parent 67611f5ac5
commit d81025eaf8

View File

@ -48,8 +48,8 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
@Nonnull @Nonnull
protected final SortedList<T> entities = SortedList.newInstance(new ArrayList<T>(30), MATH_ENTITY_COMPARATOR); protected final SortedList<T> entities = SortedList.newInstance(new ArrayList<T>(30), MATH_ENTITY_COMPARATOR);
@GuardedBy("this") @GuardedBy("this")
@Nonnull @Nullable
protected final List<String> entityNames = new ArrayList<>(); private List<String> entityNames;
@GuardedBy("this") @GuardedBy("this")
@Nonnull @Nonnull
protected final SortedList<T> systemEntities = SortedList.newInstance(new ArrayList<T>(30), MATH_ENTITY_COMPARATOR); protected final SortedList<T> systemEntities = SortedList.newInstance(new ArrayList<T>(30), MATH_ENTITY_COMPARATOR);
@ -123,7 +123,7 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
if (!contains(entity.getName(), this.entities)) { if (!contains(entity.getName(), this.entities)) {
addEntity(entity, this.entities); addEntity(entity, this.entities);
this.entityNames.clear(); this.entityNames = null;
} }
} }
} }
@ -140,7 +140,7 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
final T existingEntity = entity.isIdDefined() ? getById(entity.getId()) : get(entity.getName()); final T existingEntity = entity.isIdDefined() ? getById(entity.getId()) : get(entity.getName());
if (existingEntity == null) { if (existingEntity == null) {
addEntity(entity, entities); addEntity(entity, entities);
entityNames.clear(); this.entityNames = null;
if (entity.isSystem()) { if (entity.isSystem()) {
systemEntities.add(entity); systemEntities.add(entity);
} }
@ -148,7 +148,7 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
} else { } else {
existingEntity.copy(entity); existingEntity.copy(entity);
this.entities.sort(); this.entities.sort();
this.entityNames.clear(); this.entityNames = null;
this.systemEntities.sort(); this.systemEntities.sort();
return existingEntity; return existingEntity;
} }
@ -160,7 +160,7 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
if (!entity.isSystem()) { if (!entity.isSystem()) {
final T removed = removeByName(entities, entity.getName()); final T removed = removeByName(entities, entity.getName());
if (removed != null) { if (removed != null) {
this.entityNames.clear(); this.entityNames = null;
} }
} }
} }
@ -169,20 +169,17 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
@Nonnull @Nonnull
public List<String> getNames() { public List<String> getNames() {
synchronized (this) { synchronized (this) {
if (!entityNames.isEmpty()) { if (entityNames != null) {
// if the registry is not initialized yet we expect entityNames to be updated on a return entityNames;
// background thread => return its copy
return !initialized ? new ArrayList<>(entityNames) : entityNames;
} }
entityNames = new ArrayList<>(entities.size());
for (T entity : entities) { for (T entity : entities) {
final String name = entity.getName(); final String name = entity.getName();
if (!Strings.isEmpty(name)) { if (!Strings.isEmpty(name)) {
entityNames.add(name); entityNames.add(name);
} }
} }
// if the registry is not initialized yet we expect entityNames to be updated on a return entityNames;
// background thread => return its copy
return !initialized ? new ArrayList<>(entityNames) : entityNames;
} }
} }