1919import java .lang .reflect .Method ;
2020import java .util .Collection ;
2121import java .util .Collections ;
22+ import java .util .IdentityHashMap ;
2223import java .util .LinkedHashSet ;
2324import java .util .Map ;
2425import java .util .Set ;
@@ -111,7 +112,7 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
111112
112113 private final Set <Class <?>> nonAnnotatedClasses = Collections .newSetFromMap (new ConcurrentHashMap <>(64 ));
113114
114- private final Map <Object , Set <ScheduledTask >> scheduledTasks = new ConcurrentHashMap <>(16 );
115+ private final Map <Object , Set <ScheduledTask >> scheduledTasks = new IdentityHashMap <>(16 );
115116
116117
117118 @ Override
@@ -261,8 +262,8 @@ public Object postProcessAfterInitialization(final Object bean, String beanName)
261262 new MethodIntrospector .MetadataLookup <Set <Scheduled >>() {
262263 @ Override
263264 public Set <Scheduled > inspect (Method method ) {
264- Set <Scheduled > scheduledMethods =
265- AnnotatedElementUtils . getMergedRepeatableAnnotations ( method , Scheduled .class , Schedules .class );
265+ Set <Scheduled > scheduledMethods = AnnotatedElementUtils . getMergedRepeatableAnnotations (
266+ method , Scheduled .class , Schedules .class );
266267 return (!scheduledMethods .isEmpty () ? scheduledMethods : null );
267268 }
268269 });
@@ -300,11 +301,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
300301 String errorMessage =
301302 "Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required" ;
302303
303- Set <ScheduledTask > tasks = this .scheduledTasks .get (bean );
304- if (tasks == null ) {
305- tasks = new LinkedHashSet <>(4 );
306- this .scheduledTasks .put (bean , tasks );
307- }
304+ Set <ScheduledTask > tasks = new LinkedHashSet <>(4 );
308305
309306 // Determine initial delay
310307 long initialDelay = scheduled .initialDelay ();
@@ -398,6 +395,16 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
398395
399396 // Check whether we had any attribute set
400397 Assert .isTrue (processedSchedule , errorMessage );
398+
399+ // Finally register the scheduled tasks
400+ synchronized (this .scheduledTasks ) {
401+ Set <ScheduledTask > registeredTasks = this .scheduledTasks .get (bean );
402+ if (registeredTasks == null ) {
403+ registeredTasks = new LinkedHashSet <>(4 );
404+ this .scheduledTasks .put (bean , registeredTasks );
405+ }
406+ registeredTasks .addAll (tasks );
407+ }
401408 }
402409 catch (IllegalArgumentException ex ) {
403410 throw new IllegalStateException (
@@ -408,7 +415,10 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
408415
409416 @ Override
410417 public void postProcessBeforeDestruction (Object bean , String beanName ) {
411- Set <ScheduledTask > tasks = this .scheduledTasks .remove (bean );
418+ Set <ScheduledTask > tasks ;
419+ synchronized (this .scheduledTasks ) {
420+ tasks = this .scheduledTasks .remove (bean );
421+ }
412422 if (tasks != null ) {
413423 for (ScheduledTask task : tasks ) {
414424 task .cancel ();
@@ -418,18 +428,22 @@ public void postProcessBeforeDestruction(Object bean, String beanName) {
418428
419429 @ Override
420430 public boolean requiresDestruction (Object bean ) {
421- return this .scheduledTasks .containsKey (bean );
431+ synchronized (this .scheduledTasks ) {
432+ return this .scheduledTasks .containsKey (bean );
433+ }
422434 }
423435
424436 @ Override
425437 public void destroy () {
426- Collection <Set <ScheduledTask >> allTasks = this .scheduledTasks .values ();
427- for (Set <ScheduledTask > tasks : allTasks ) {
428- for (ScheduledTask task : tasks ) {
429- task .cancel ();
438+ synchronized (this .scheduledTasks ) {
439+ Collection <Set <ScheduledTask >> allTasks = this .scheduledTasks .values ();
440+ for (Set <ScheduledTask > tasks : allTasks ) {
441+ for (ScheduledTask task : tasks ) {
442+ task .cancel ();
443+ }
430444 }
445+ this .scheduledTasks .clear ();
431446 }
432- this .scheduledTasks .clear ();
433447 this .registrar .destroy ();
434448 }
435449
0 commit comments