[LANG-586] clear ThreadLocal recursion registry (compatibly with existing tests, first pass)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@906673 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c98d0840bc
commit
5c3ec55e15
|
@ -19,9 +19,10 @@ package org.apache.commons.lang3.builder;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ClassUtils;
|
import org.apache.commons.lang3.ClassUtils;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
@ -133,14 +134,7 @@ public abstract class ToStringStyle implements Serializable {
|
||||||
* to detect cyclical object references and avoid infinite loops.
|
* to detect cyclical object references and avoid infinite loops.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
private static final ThreadLocal<Set<Object>> registry = new ThreadLocal<Set<Object>>() {
|
private static final ThreadLocal<WeakHashMap<Object, Object>> REGISTRY = new ThreadLocal<WeakHashMap<Object,Object>>();
|
||||||
@Override
|
|
||||||
protected Set<Object> initialValue() {
|
|
||||||
// The HashSet implementation is not synchronized,
|
|
||||||
// which is just what we need here.
|
|
||||||
return new HashSet<Object>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -151,7 +145,8 @@ public abstract class ToStringStyle implements Serializable {
|
||||||
* @return Set the registry of objects being traversed
|
* @return Set the registry of objects being traversed
|
||||||
*/
|
*/
|
||||||
static Set<Object> getRegistry() {
|
static Set<Object> getRegistry() {
|
||||||
return registry.get();
|
WeakHashMap<Object, Object> m = REGISTRY.get();
|
||||||
|
return m == null ? Collections.<Object> emptySet() : m.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,7 +175,15 @@ public abstract class ToStringStyle implements Serializable {
|
||||||
*/
|
*/
|
||||||
static void register(Object value) {
|
static void register(Object value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
getRegistry().add(value);
|
WeakHashMap<Object, Object> m;
|
||||||
|
synchronized (ToStringStyle.class) {
|
||||||
|
m = REGISTRY.get();
|
||||||
|
if (m == null) {
|
||||||
|
m = new WeakHashMap<Object, Object>();
|
||||||
|
REGISTRY.set(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.put(value, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +200,18 @@ public abstract class ToStringStyle implements Serializable {
|
||||||
* The object to unregister.
|
* The object to unregister.
|
||||||
*/
|
*/
|
||||||
static void unregister(Object value) {
|
static void unregister(Object value) {
|
||||||
getRegistry().remove(value);
|
if (value != null) {
|
||||||
|
WeakHashMap<Object, Object> m;
|
||||||
|
synchronized (ToStringStyle.class) {
|
||||||
|
m = REGISTRY.get();
|
||||||
|
if (m != null) {
|
||||||
|
m.remove(value);
|
||||||
|
if (m.isEmpty()) {
|
||||||
|
REGISTRY.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue