11/*
2- * Copyright 2002-2016 the original author or authors.
2+ * Copyright 2002-2017 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.
2727
2828/**
2929 * A {@link org.springframework.util.concurrent.ListenableFuture ListenableFuture}
30- * whose value can be set via {@link #set(Object )} or
31- * {@link #setException(Throwable)}. It may also be cancelled.
30+ * whose value can be set via {@link #set(T )} or {@link #setException(Throwable)}.
31+ * It may also be cancelled.
3232 *
3333 * <p>Inspired by {@code com.google.common.util.concurrent.SettableFuture}.
3434 *
3535 * @author Mattias Severson
3636 * @author Rossen Stoyanchev
37+ * @author Juergen Hoeller
3738 * @since 4.1
3839 */
3940public class SettableListenableFuture <T > implements ListenableFuture <T > {
@@ -92,8 +93,8 @@ public void addCallback(SuccessCallback<? super T> successCallback, FailureCallb
9293
9394 @ Override
9495 public boolean cancel (boolean mayInterruptIfRunning ) {
95- this .settableTask .setCancelled ();
96- boolean cancelled = this .listenableFuture .cancel (mayInterruptIfRunning );
96+ boolean cancelled = this .settableTask .setCancelled ();
97+ this .listenableFuture .cancel (mayInterruptIfRunning );
9798 if (cancelled && mayInterruptIfRunning ) {
9899 interruptTask ();
99100 }
@@ -102,21 +103,21 @@ public boolean cancel(boolean mayInterruptIfRunning) {
102103
103104 @ Override
104105 public boolean isCancelled () {
105- return this .listenableFuture .isCancelled ();
106+ return this .settableTask .isCancelled ();
106107 }
107108
108109 @ Override
109110 public boolean isDone () {
110- return this .listenableFuture .isDone ();
111+ return this .settableTask .isDone ();
111112 }
112113
113114 /**
114115 * Retrieve the value.
115- * <p>Will return the value if it has been set via {@link #set(Object)},
116- * throw an {@link java.util.concurrent.ExecutionException} if it has been
117- * set via {@link #setException(Throwable)} or throw a
118- * {@link java.util.concurrent.CancellationException} if it has been cancelled.
119- * @return The value associated with this future.
116+ * <p>This method returns the value if it has been set via {@link #set(Object)},
117+ * throws an {@link java.util.concurrent.ExecutionException} if an exception has
118+ * been set via {@link #setException(Throwable)}, or throws a
119+ * {@link java.util.concurrent.CancellationException} if the future has been cancelled.
120+ * @return the value associated with this future
120121 */
121122 @ Override
122123 public T get () throws InterruptedException , ExecutionException {
@@ -125,13 +126,13 @@ public T get() throws InterruptedException, ExecutionException {
125126
126127 /**
127128 * Retrieve the value.
128- * <p>Will return the value if it has been set via {@link #set(Object)},
129- * throw an {@link java.util.concurrent.ExecutionException} if it has been
130- * set via {@link #setException(Throwable)} or throw a
131- * {@link java.util.concurrent.CancellationException} if it has been cancelled.
132- * @param timeout the maximum time to wait.
133- * @param unit the time unit of the timeout argument.
134- * @return The value associated with this future.
129+ * <p>This method returns the value if it has been set via {@link #set(Object)},
130+ * throws an {@link java.util.concurrent.ExecutionException} if an exception has
131+ * been set via {@link #setException(Throwable)}, or throws a
132+ * {@link java.util.concurrent.CancellationException} if the future has been cancelled.
133+ * @param timeout the maximum time to wait
134+ * @param unit the unit of the timeout argument
135+ * @return the value associated with this future
135136 */
136137 @ Override
137138 public T get (long timeout , TimeUnit unit ) throws InterruptedException , ExecutionException , TimeoutException {
@@ -142,7 +143,7 @@ public T get(long timeout, TimeUnit unit) throws InterruptedException, Execution
142143 * Subclasses can override this method to implement interruption of the future's
143144 * computation. The method is invoked automatically by a successful call to
144145 * {@link #cancel(boolean) cancel(true)}.
145- * <p>The default implementation does nothing .
146+ * <p>The default implementation is empty .
146147 */
147148 protected void interruptTask () {
148149 }
@@ -152,26 +153,28 @@ private static class SettableTask<T> implements Callable<T> {
152153
153154 private static final Object NO_VALUE = new Object ();
154155
155- private final AtomicReference < Object > value = new AtomicReference < Object >( NO_VALUE );
156+ private static final Object CANCELLED = new Object ( );
156157
157- private volatile boolean cancelled = false ;
158+ private final AtomicReference < Object > value = new AtomicReference < Object >( NO_VALUE ) ;
158159
159160 public boolean setValue (T value ) {
160- if (this .cancelled ) {
161- return false ;
162- }
163161 return this .value .compareAndSet (NO_VALUE , value );
164162 }
165163
166164 public boolean setException (Throwable exception ) {
167- if (this .cancelled ) {
168- return false ;
169- }
170165 return this .value .compareAndSet (NO_VALUE , exception );
171166 }
172167
173- public void setCancelled () {
174- this .cancelled = true ;
168+ public boolean setCancelled () {
169+ return this .value .compareAndSet (NO_VALUE , CANCELLED );
170+ }
171+
172+ public boolean isCancelled () {
173+ return (this .value .get () == CANCELLED );
174+ }
175+
176+ public boolean isDone () {
177+ return (this .value .get () != NO_VALUE );
175178 }
176179
177180 @ SuppressWarnings ("unchecked" )
0 commit comments