From e7231f39cf8e4186a2f6ab2a50c377afc6b862db Mon Sep 17 00:00:00 2001 From: "Philip K. Warren" Date: Tue, 20 Dec 2016 15:46:58 -0600 Subject: [PATCH] Update PropertyWrapper to be thread safe. Update the callbacks collection in PropertyWrapper to be thread safe (similar to DynamicProperty). Remove runnable entries from callbacks collection after removing from DynamicProperty. --- .../java/com/netflix/config/PropertyWrapper.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/archaius-core/src/main/java/com/netflix/config/PropertyWrapper.java b/archaius-core/src/main/java/com/netflix/config/PropertyWrapper.java index 637df5161..4514676b6 100644 --- a/archaius-core/src/main/java/com/netflix/config/PropertyWrapper.java +++ b/archaius-core/src/main/java/com/netflix/config/PropertyWrapper.java @@ -15,10 +15,11 @@ */ package com.netflix.config; +import java.util.HashSet; import java.util.IdentityHashMap; -import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; -import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +39,7 @@ public abstract class PropertyWrapper implements Property { private static final IdentityHashMap, Object> SUBCLASSES_WITH_NO_CALLBACK = new IdentityHashMap, Object>(); private static final Logger logger = LoggerFactory.getLogger(PropertyWrapper.class); - private final List callbackList = Lists.newArrayList(); + private final Set callbacks = new CopyOnWriteArraySet(); static { PropertyWrapper.registerSubClassWithNoCallback(DynamicIntProperty.class); @@ -81,7 +82,7 @@ public void run() { } }; this.prop.addCallback(callback); - callbackList.add(callback); + callbacks.add(callback); this.prop.addValidator(new PropertyChangeValidator() { @Override public void validate(String newValue) { @@ -149,7 +150,7 @@ public long getChangedTimestamp() { public void addCallback(Runnable callback) { if (callback != null) { prop.addCallback(callback); - callbackList.add(callback); + callbacks.add(callback); } } @@ -158,9 +159,11 @@ public void addCallback(Runnable callback) { */ @Override public void removeAllCallbacks() { - for (Runnable callback: callbackList) { + final Set callbacksToRemove = new HashSet(callbacks); + for (Runnable callback : callbacksToRemove) { prop.removeCallback(callback); } + callbacks.removeAll(callbacksToRemove); } /**