Skip to content

Commit 0f522cf

Browse files
committed
Calling cancel on a Future returned by a TaskScheduler works reliably now
Issue: SPR-9821
1 parent da75eae commit 0f522cf

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -49,9 +49,9 @@ class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements Sc
4949

5050
private final ScheduledExecutorService executor;
5151

52-
private volatile ScheduledFuture currentFuture;
52+
private ScheduledFuture currentFuture;
5353

54-
private volatile Date scheduledExecutionTime;
54+
private Date scheduledExecutionTime;
5555

5656
private final Object triggerContextMonitor = new Object();
5757

@@ -82,35 +82,47 @@ public void run() {
8282
Date completionTime = new Date();
8383
synchronized (this.triggerContextMonitor) {
8484
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
85-
}
86-
if (!this.currentFuture.isCancelled()) {
87-
schedule();
85+
if (!this.currentFuture.isCancelled()) {
86+
schedule();
87+
}
8888
}
8989
}
9090

9191

9292
public boolean cancel(boolean mayInterruptIfRunning) {
93-
return this.currentFuture.cancel(mayInterruptIfRunning);
93+
synchronized (this.triggerContextMonitor) {
94+
return this.currentFuture.cancel(mayInterruptIfRunning);
95+
}
9496
}
9597

9698
public boolean isCancelled() {
97-
return this.currentFuture.isCancelled();
99+
synchronized (this.triggerContextMonitor) {
100+
return this.currentFuture.isCancelled();
101+
}
98102
}
99103

100104
public boolean isDone() {
101-
return this.currentFuture.isDone();
105+
synchronized (this.triggerContextMonitor) {
106+
return this.currentFuture.isDone();
107+
}
102108
}
103109

104110
public Object get() throws InterruptedException, ExecutionException {
105-
return this.currentFuture.get();
111+
synchronized (this.triggerContextMonitor) {
112+
return this.currentFuture.get();
113+
}
106114
}
107115

108116
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
109-
return this.currentFuture.get(timeout, unit);
117+
synchronized (this.triggerContextMonitor) {
118+
return this.currentFuture.get(timeout, unit);
119+
}
110120
}
111121

112122
public long getDelay(TimeUnit unit) {
113-
return this.currentFuture.getDelay(unit);
123+
synchronized (this.triggerContextMonitor) {
124+
return this.currentFuture.getDelay(unit);
125+
}
114126
}
115127

116128
public int compareTo(Delayed other) {

0 commit comments

Comments
 (0)