提交 d7720ed4 编写于 作者: oldratlee's avatar oldratlee 🔥

! fix bug: WeakHashMap in Snapshot led to captured values GCed before replay unexpectedly

上级 ce9999a5
...@@ -3,6 +3,7 @@ package com.alibaba.ttl; ...@@ -3,6 +3,7 @@ package com.alibaba.ttl;
import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
...@@ -371,16 +372,16 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -371,16 +372,16 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
return new Snapshot(captureTtlValues(), captureThreadLocalValues()); return new Snapshot(captureTtlValues(), captureThreadLocalValues());
} }
private static WeakHashMap<TransmittableThreadLocal<Object>, Object> captureTtlValues() { private static HashMap<TransmittableThreadLocal<Object>, Object> captureTtlValues() {
WeakHashMap<TransmittableThreadLocal<Object>, Object> ttl2Value = new WeakHashMap<TransmittableThreadLocal<Object>, Object>(); HashMap<TransmittableThreadLocal<Object>, Object> ttl2Value = new HashMap<TransmittableThreadLocal<Object>, Object>();
for (TransmittableThreadLocal<Object> threadLocal : holder.get().keySet()) { for (TransmittableThreadLocal<Object> threadLocal : holder.get().keySet()) {
ttl2Value.put(threadLocal, threadLocal.copyValue()); ttl2Value.put(threadLocal, threadLocal.copyValue());
} }
return ttl2Value; return ttl2Value;
} }
private static WeakHashMap<ThreadLocal<Object>, Object> captureThreadLocalValues() { private static HashMap<ThreadLocal<Object>, Object> captureThreadLocalValues() {
final WeakHashMap<ThreadLocal<Object>, Object> threadLocal2Value = new WeakHashMap<ThreadLocal<Object>, Object>(); final HashMap<ThreadLocal<Object>, Object> threadLocal2Value = new HashMap<ThreadLocal<Object>, Object>();
for (Map.Entry<ThreadLocal<Object>, TtlCopier<Object>> entry : threadLocalHolder.entrySet()) { for (Map.Entry<ThreadLocal<Object>, TtlCopier<Object>> entry : threadLocalHolder.entrySet()) {
final ThreadLocal<Object> threadLocal = entry.getKey(); final ThreadLocal<Object> threadLocal = entry.getKey();
final TtlCopier<Object> copier = entry.getValue(); final TtlCopier<Object> copier = entry.getValue();
...@@ -406,8 +407,8 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -406,8 +407,8 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
} }
@NonNull @NonNull
private static WeakHashMap<TransmittableThreadLocal<Object>, Object> replayTtlValues(@NonNull WeakHashMap<TransmittableThreadLocal<Object>, Object> captured) { private static HashMap<TransmittableThreadLocal<Object>, Object> replayTtlValues(@NonNull HashMap<TransmittableThreadLocal<Object>, Object> captured) {
WeakHashMap<TransmittableThreadLocal<Object>, Object> backup = new WeakHashMap<TransmittableThreadLocal<Object>, Object>(); HashMap<TransmittableThreadLocal<Object>, Object> backup = new HashMap<TransmittableThreadLocal<Object>, Object>();
for (final Iterator<TransmittableThreadLocal<Object>> iterator = holder.get().keySet().iterator(); iterator.hasNext(); ) { for (final Iterator<TransmittableThreadLocal<Object>> iterator = holder.get().keySet().iterator(); iterator.hasNext(); ) {
TransmittableThreadLocal<Object> threadLocal = iterator.next(); TransmittableThreadLocal<Object> threadLocal = iterator.next();
...@@ -432,8 +433,8 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -432,8 +433,8 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
return backup; return backup;
} }
private static WeakHashMap<ThreadLocal<Object>, Object> replayThreadLocalValues(@NonNull WeakHashMap<ThreadLocal<Object>, Object> captured) { private static HashMap<ThreadLocal<Object>, Object> replayThreadLocalValues(@NonNull HashMap<ThreadLocal<Object>, Object> captured) {
final WeakHashMap<ThreadLocal<Object>, Object> backup = new WeakHashMap<ThreadLocal<Object>, Object>(); final HashMap<ThreadLocal<Object>, Object> backup = new HashMap<ThreadLocal<Object>, Object>();
for (Map.Entry<ThreadLocal<Object>, Object> entry : captured.entrySet()) { for (Map.Entry<ThreadLocal<Object>, Object> entry : captured.entrySet()) {
final ThreadLocal<Object> threadLocal = entry.getKey(); final ThreadLocal<Object> threadLocal = entry.getKey();
...@@ -456,9 +457,9 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -456,9 +457,9 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
*/ */
@NonNull @NonNull
public static Object clear() { public static Object clear() {
final WeakHashMap<TransmittableThreadLocal<Object>, Object> ttl2Value = new WeakHashMap<TransmittableThreadLocal<Object>, Object>(); final HashMap<TransmittableThreadLocal<Object>, Object> ttl2Value = new HashMap<TransmittableThreadLocal<Object>, Object>();
final WeakHashMap<ThreadLocal<Object>, Object> threadLocal2Value = new WeakHashMap<ThreadLocal<Object>, Object>(); final HashMap<ThreadLocal<Object>, Object> threadLocal2Value = new HashMap<ThreadLocal<Object>, Object>();
for (Map.Entry<ThreadLocal<Object>, TtlCopier<Object>> entry : threadLocalHolder.entrySet()) { for (Map.Entry<ThreadLocal<Object>, TtlCopier<Object>> entry : threadLocalHolder.entrySet()) {
final ThreadLocal<Object> threadLocal = entry.getKey(); final ThreadLocal<Object> threadLocal = entry.getKey();
threadLocal2Value.put(threadLocal, threadLocalClearMark); threadLocal2Value.put(threadLocal, threadLocalClearMark);
...@@ -482,7 +483,7 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -482,7 +483,7 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
restoreThreadLocalValues(backupSnapshot.threadLocal2Value); restoreThreadLocalValues(backupSnapshot.threadLocal2Value);
} }
private static void restoreTtlValues(@NonNull WeakHashMap<TransmittableThreadLocal<Object>, Object> backup) { private static void restoreTtlValues(@NonNull HashMap<TransmittableThreadLocal<Object>, Object> backup) {
// call afterExecute callback // call afterExecute callback
doExecuteCallback(false); doExecuteCallback(false);
...@@ -501,14 +502,14 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -501,14 +502,14 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
setTtlValuesTo(backup); setTtlValuesTo(backup);
} }
private static void setTtlValuesTo(@NonNull WeakHashMap<TransmittableThreadLocal<Object>, Object> ttlValues) { private static void setTtlValuesTo(@NonNull HashMap<TransmittableThreadLocal<Object>, Object> ttlValues) {
for (Map.Entry<TransmittableThreadLocal<Object>, Object> entry : ttlValues.entrySet()) { for (Map.Entry<TransmittableThreadLocal<Object>, Object> entry : ttlValues.entrySet()) {
TransmittableThreadLocal<Object> threadLocal = entry.getKey(); TransmittableThreadLocal<Object> threadLocal = entry.getKey();
threadLocal.set(entry.getValue()); threadLocal.set(entry.getValue());
} }
} }
private static void restoreThreadLocalValues(@NonNull WeakHashMap<ThreadLocal<Object>, Object> backup) { private static void restoreThreadLocalValues(@NonNull HashMap<ThreadLocal<Object>, Object> backup) {
for (Map.Entry<ThreadLocal<Object>, Object> entry : backup.entrySet()) { for (Map.Entry<ThreadLocal<Object>, Object> entry : backup.entrySet()) {
final ThreadLocal<Object> threadLocal = entry.getKey(); final ThreadLocal<Object> threadLocal = entry.getKey();
threadLocal.set(entry.getValue()); threadLocal.set(entry.getValue());
...@@ -516,10 +517,10 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple ...@@ -516,10 +517,10 @@ public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> imple
} }
private static class Snapshot { private static class Snapshot {
final WeakHashMap<TransmittableThreadLocal<Object>, Object> ttl2Value; final HashMap<TransmittableThreadLocal<Object>, Object> ttl2Value;
final WeakHashMap<ThreadLocal<Object>, Object> threadLocal2Value; final HashMap<ThreadLocal<Object>, Object> threadLocal2Value;
private Snapshot(WeakHashMap<TransmittableThreadLocal<Object>, Object> ttl2Value, WeakHashMap<ThreadLocal<Object>, Object> threadLocal2Value) { private Snapshot(HashMap<TransmittableThreadLocal<Object>, Object> ttl2Value, HashMap<ThreadLocal<Object>, Object> threadLocal2Value) {
this.ttl2Value = ttl2Value; this.ttl2Value = ttl2Value;
this.threadLocal2Value = threadLocal2Value; this.threadLocal2Value = threadLocal2Value;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册