@@ -497,7 +497,7 @@ private Class<?> getCustomTarget(Class<?> sourceType, @Nullable Class<?> targetT
497
497
*/
498
498
static class ConversionTargetsCache {
499
499
500
- private Map <Class <?>, TargetTypes > customReadTargetTypes = new HashMap <>();
500
+ private volatile Map <Class <?>, TargetTypes > customReadTargetTypes = new HashMap <>();
501
501
502
502
/**
503
503
* Get or compute a target type given its {@code sourceType}. Returns a cached {@link Optional} if the value
@@ -531,10 +531,19 @@ public Class<?> computeIfAbsent(Class<?> sourceType, Class<?> targetType,
531
531
532
532
if (targetTypes == null ) {
533
533
534
- Map <Class <?>, TargetTypes > customReadTargetTypes = new HashMap <>(this .customReadTargetTypes );
535
- targetTypes = new TargetTypes (sourceType );
536
- customReadTargetTypes .put (sourceType , targetTypes );
537
- this .customReadTargetTypes = customReadTargetTypes ;
534
+ synchronized (this ) {
535
+
536
+ TargetTypes customReadTarget = customReadTargetTypes .get (sourceType );
537
+ if (customReadTarget != null ) {
538
+ targetTypes = customReadTarget ;
539
+ } else {
540
+
541
+ Map <Class <?>, TargetTypes > customReadTargetTypes = new HashMap <>(this .customReadTargetTypes );
542
+ targetTypes = new TargetTypes (sourceType );
543
+ customReadTargetTypes .put (sourceType , targetTypes );
544
+ this .customReadTargetTypes = customReadTargetTypes ;
545
+ }
546
+ }
538
547
}
539
548
540
549
return targetTypes .computeIfAbsent (targetType , mappingFunction );
@@ -554,7 +563,7 @@ interface AbsentTargetTypeMarker {}
554
563
static class TargetTypes {
555
564
556
565
private final Class <?> sourceType ;
557
- private Map <Class <?>, Class <?>> conversionTargets = new HashMap <>();
566
+ private volatile Map <Class <?>, Class <?>> conversionTargets = new HashMap <>();
558
567
559
568
TargetTypes (Class <?> sourceType ) {
560
569
this .sourceType = sourceType ;
@@ -576,11 +585,19 @@ public Class<?> computeIfAbsent(Class<?> targetType, Function<ConvertiblePair, C
576
585
577
586
if (optionalTarget == null ) {
578
587
579
- optionalTarget = mappingFunction .apply (new ConvertiblePair (sourceType , targetType ));
588
+ synchronized (this ) {
589
+
590
+ Class <?> conversionTarget = conversionTargets .get (targetType );
591
+ if (conversionTarget != null ) {
592
+ optionalTarget = conversionTarget ;
593
+ } else {
580
594
581
- Map <Class <?>, Class <?>> conversionTargets = new HashMap <>(this .conversionTargets );
582
- conversionTargets .put (targetType , optionalTarget == null ? Void .class : optionalTarget );
583
- this .conversionTargets = conversionTargets ;
595
+ optionalTarget = mappingFunction .apply (new ConvertiblePair (sourceType , targetType ));
596
+ Map <Class <?>, Class <?>> conversionTargets = new HashMap <>(this .conversionTargets );
597
+ conversionTargets .put (targetType , optionalTarget == null ? Void .class : optionalTarget );
598
+ this .conversionTargets = conversionTargets ;
599
+ }
600
+ }
584
601
}
585
602
586
603
return Void .class .equals (optionalTarget ) ? null : optionalTarget ;
0 commit comments