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 ;
@@ -113,7 +114,7 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
113114 Collections .newSetFromMap (new ConcurrentHashMap <Class <?>, Boolean >(64 ));
114115
115116 private final Map <Object , Set <ScheduledTask >> scheduledTasks =
116- new ConcurrentHashMap <Object , Set <ScheduledTask >>(16 );
117+ new IdentityHashMap <Object , Set <ScheduledTask >>(16 );
117118
118119
119120 @ Override
@@ -263,8 +264,8 @@ public Object postProcessAfterInitialization(final Object bean, String beanName)
263264 new MethodIntrospector .MetadataLookup <Set <Scheduled >>() {
264265 @ Override
265266 public Set <Scheduled > inspect (Method method ) {
266- Set <Scheduled > scheduledMethods =
267- AnnotatedElementUtils . getMergedRepeatableAnnotations ( method , Scheduled .class , Schedules .class );
267+ Set <Scheduled > scheduledMethods = AnnotatedElementUtils . getMergedRepeatableAnnotations (
268+ method , Scheduled .class , Schedules .class );
268269 return (!scheduledMethods .isEmpty () ? scheduledMethods : null );
269270 }
270271 });
@@ -302,11 +303,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
302303 String errorMessage =
303304 "Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required" ;
304305
305- Set <ScheduledTask > tasks = this .scheduledTasks .get (bean );
306- if (tasks == null ) {
307- tasks = new LinkedHashSet <ScheduledTask >(4 );
308- this .scheduledTasks .put (bean , tasks );
309- }
306+ Set <ScheduledTask > tasks = new LinkedHashSet <ScheduledTask >(4 );
310307
311308 // Determine initial delay
312309 long initialDelay = scheduled .initialDelay ();
@@ -400,6 +397,16 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
400397
401398 // Check whether we had any attribute set
402399 Assert .isTrue (processedSchedule , errorMessage );
400+
401+ // Finally register the scheduled tasks
402+ synchronized (this .scheduledTasks ) {
403+ Set <ScheduledTask > registeredTasks = this .scheduledTasks .get (bean );
404+ if (registeredTasks == null ) {
405+ registeredTasks = new LinkedHashSet <ScheduledTask >(4 );
406+ this .scheduledTasks .put (bean , registeredTasks );
407+ }
408+ registeredTasks .addAll (tasks );
409+ }
403410 }
404411 catch (IllegalArgumentException ex ) {
405412 throw new IllegalStateException (
@@ -410,7 +417,10 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
410417
411418 @ Override
412419 public void postProcessBeforeDestruction (Object bean , String beanName ) {
413- Set <ScheduledTask > tasks = this .scheduledTasks .remove (bean );
420+ Set <ScheduledTask > tasks ;
421+ synchronized (this .scheduledTasks ) {
422+ tasks = this .scheduledTasks .remove (bean );
423+ }
414424 if (tasks != null ) {
415425 for (ScheduledTask task : tasks ) {
416426 task .cancel ();
@@ -420,18 +430,22 @@ public void postProcessBeforeDestruction(Object bean, String beanName) {
420430
421431 @ Override
422432 public boolean requiresDestruction (Object bean ) {
423- return this .scheduledTasks .containsKey (bean );
433+ synchronized (this .scheduledTasks ) {
434+ return this .scheduledTasks .containsKey (bean );
435+ }
424436 }
425437
426438 @ Override
427439 public void destroy () {
428- Collection <Set <ScheduledTask >> allTasks = this .scheduledTasks .values ();
429- for (Set <ScheduledTask > tasks : allTasks ) {
430- for (ScheduledTask task : tasks ) {
431- task .cancel ();
440+ synchronized (this .scheduledTasks ) {
441+ Collection <Set <ScheduledTask >> allTasks = this .scheduledTasks .values ();
442+ for (Set <ScheduledTask > tasks : allTasks ) {
443+ for (ScheduledTask task : tasks ) {
444+ task .cancel ();
445+ }
432446 }
447+ this .scheduledTasks .clear ();
433448 }
434- this .scheduledTasks .clear ();
435449 this .registrar .destroy ();
436450 }
437451
0 commit comments