Skip to content

Commit

Permalink
Update PropertyWrapper to be thread safe.
Browse files Browse the repository at this point in the history
Update the callbacks collection in PropertyWrapper to be thread safe
(similar to DynamicProperty). Remove runnable entries from callbacks
collection after removing from DynamicProperty.
  • Loading branch information
Philip K. Warren committed Dec 20, 2016
1 parent 9b3e5d2 commit e7231f3
Showing 1 changed file with 9 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -38,7 +39,7 @@ public abstract class PropertyWrapper<V> implements Property<V> {
private static final IdentityHashMap<Class<? extends PropertyWrapper>, Object> SUBCLASSES_WITH_NO_CALLBACK
= new IdentityHashMap<Class<? extends PropertyWrapper>, Object>();
private static final Logger logger = LoggerFactory.getLogger(PropertyWrapper.class);
private final List<Runnable> callbackList = Lists.newArrayList();
private final Set<Runnable> callbacks = new CopyOnWriteArraySet<Runnable>();

static {
PropertyWrapper.registerSubClassWithNoCallback(DynamicIntProperty.class);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -149,7 +150,7 @@ public long getChangedTimestamp() {
public void addCallback(Runnable callback) {
if (callback != null) {
prop.addCallback(callback);
callbackList.add(callback);
callbacks.add(callback);
}
}

Expand All @@ -158,9 +159,11 @@ public void addCallback(Runnable callback) {
*/
@Override
public void removeAllCallbacks() {
for (Runnable callback: callbackList) {
final Set<Runnable> callbacksToRemove = new HashSet<Runnable>(callbacks);
for (Runnable callback : callbacksToRemove) {
prop.removeCallback(callback);
}
callbacks.removeAll(callbacksToRemove);
}

/**
Expand Down

0 comments on commit e7231f3

Please sign in to comment.