@@ -48,8 +48,8 @@ public class DifferDispatcher
4848 private final IsIgnoredResolver isIgnoredResolver ;
4949 private final IsReturnableResolver isReturnableResolver ;
5050 private final PropertyAccessExceptionHandlerResolver propertyAccessExceptionHandlerResolver ;
51- CircularReferenceDetector workingCircularReferenceDetector ;
52- CircularReferenceDetector baseCircularReferenceDetector ;
51+ private static final ThreadLocal < CircularReferenceDetector > workingThreadLocal = new ThreadLocal < CircularReferenceDetector >() ;
52+ private static final ThreadLocal < CircularReferenceDetector > baseThreadLocal = new ThreadLocal < CircularReferenceDetector >() ;
5353
5454 public DifferDispatcher (final DifferProvider differProvider ,
5555 final CircularReferenceDetectorFactory circularReferenceDetectorFactory ,
@@ -72,12 +72,18 @@ public DifferDispatcher(final DifferProvider differProvider,
7272 resetInstanceMemory ();
7373 }
7474
75- protected final void resetInstanceMemory ()
75+ public final void resetInstanceMemory ()
7676 {
77- workingCircularReferenceDetector = circularReferenceDetectorFactory .createCircularReferenceDetector ();
78- baseCircularReferenceDetector = circularReferenceDetectorFactory .createCircularReferenceDetector ();
77+ workingThreadLocal . set ( circularReferenceDetectorFactory .createCircularReferenceDetector () );
78+ baseThreadLocal . set ( circularReferenceDetectorFactory .createCircularReferenceDetector () );
7979 }
8080
81+ public final void clearInstanceMemory ()
82+ {
83+ workingThreadLocal .remove ();
84+ baseThreadLocal .remove ();
85+ }
86+
8187 /**
8288 * Delegates the call to an appropriate {@link Differ}.
8389 *
@@ -202,8 +208,8 @@ protected void forgetInstances(final DiffNode parentNode, final Instances instan
202208 nodePath = NodePath .withRoot ();
203209 }
204210 logger .debug ("[ {} ] Forgetting --- WORKING: {} <=> BASE: {}" , nodePath , instances .getWorking (), instances .getBase ());
205- workingCircularReferenceDetector .remove (instances .getWorking ());
206- baseCircularReferenceDetector .remove (instances .getBase ());
211+ workingThreadLocal . get () .remove (instances .getWorking ());
212+ baseThreadLocal . get () .remove (instances .getBase ());
207213 }
208214
209215 protected void rememberInstances (final DiffNode parentNode , final Instances instances )
@@ -226,17 +232,17 @@ protected void rememberInstances(final DiffNode parentNode, final Instances inst
226232
227233 private void transactionalPushToCircularReferenceDetectors (final NodePath nodePath , final Instances instances )
228234 {
229- workingCircularReferenceDetector .push (instances .getWorking (), nodePath );
235+ workingThreadLocal . get () .push (instances .getWorking (), nodePath );
230236
231237 // TODO This needs to be solved more elegantly. If the push for one of these detectors fails,
232238 // we need to make sure to revert the push to the other one, if it already happened.
233239 try
234240 {
235- baseCircularReferenceDetector .push (instances .getBase (), nodePath );
241+ baseThreadLocal . get () .push (instances .getBase (), nodePath );
236242 }
237243 catch (final CircularReferenceException e )
238244 {
239- workingCircularReferenceDetector .remove (instances .getWorking ()); // rollback
245+ workingThreadLocal . get () .remove (instances .getWorking ()); // rollback
240246 throw e ;
241247 }
242248 }
0 commit comments