建议楼主看看多线程的东东,并不难.写一个线程,把 result 初始化进去, 线程启动往里存东西就行了. 主程序要监控线程运行状态, 当线程执行完后, 再读 result.
34.public class FutureTask<V> implements Future<V>, Runnable { 35. /** Synchronization control for FutureTask */ 36. private final Sync sync; 37. 38. /** 39. * Creates a <tt>FutureTask</tt> that will upon running, execute the 40. * given <tt>Callable</tt>. 41. * 42. * @param callable the callable task 43. * @throws NullPointerException if callable is null 44. */ 45. public FutureTask(Callable<V> callable) { 46. if (callable == null) 47. throw new NullPointerException(); 48. sync = new Sync(callable); 49. } 50. 51. /** 52. * Creates a <tt>FutureTask</tt> that will upon running, execute the 53. * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the 54. * given result on successful completion. 55. * 56. * @param runnable the runnable task 57. * @param result the result to return on successful completion. If 58. * you don't need a particular result, consider using 59. * constructions of the form: 60. * <tt>Future<?> f = new FutureTask<Object>(runnable, null)</tt> 61. * @throws NullPointerException if runnable is null 62. */ 63. public FutureTask(Runnable runnable, V result) { 64. sync = new Sync(Executors.callable(runnable, result)); 65. } 66. 67. public boolean isCancelled() { 68. return sync.innerIsCancelled(); 69. } 70. 71. public boolean isDone() { 72. return sync.innerIsDone(); 73. } 74. 75. public boolean cancel(boolean mayInterruptIfRunning) { 76. return sync.innerCancel(mayInterruptIfRunning); 77. } 78. 79. public V get() throws InterruptedException, ExecutionException { 80. return sync.innerGet(); 81. } 82. 83. public V get(long timeout, TimeUnit unit) 84. throws InterruptedException, ExecutionException, TimeoutException { 85. return sync.innerGet(unit.toNanos(timeout)); 86. } 87. 88. /** 89. * Protected method invoked when this task transitions to state 90. * <tt>isDone</tt> (whether normally or via cancellation). The 91. * default implementation does nothing. Subclasses may override 92. * this method to invoke completion callbacks or perform 93. * bookkeeping. Note that you can query status inside the 94. * implementation of this method to determine whether this task 95. * has been cancelled. 96. */ 97. protected void done() { } 98. 99. /** 100. * Sets the result of this Future to the given value unless 101. * this future has already been set or has been cancelled. 102. * @param v the value 103. */ 104. protected void set(V v) { 105. sync.innerSet(v); 106. } 107. 108. /** 109. * Causes this future to report an <tt>ExecutionException</tt> 110. * with the given throwable as its cause, unless this Future has 111. * already been set or has been cancelled. 112. * @param t the cause of failure. 113. */ 114. protected void setException(Throwable t) { 115. sync.innerSetException(t); 116. } 117. 118. /** 119. * Sets this Future to the result of computation unless 120. * it has been cancelled. 121. */ 122. public void run() { 123. sync.innerRun(); 124. } 125. 126. /** 127. * Executes the computation without setting its result, and then 128. * resets this Future to initial state, failing to do so if the 129. * computation encounters an exception or is cancelled. This is 130. * designed for use with tasks that intrinsically execute more 131. * than once. 132. * @return true if successfully run and reset 133. */ 134. protected boolean runAndReset() { 135. return sync.innerRunAndReset(); 136. } 137. 138. /** 139. * Synchronization control for FutureTask. Note that this must be 140. * a non-static inner class in order to invoke the protected 141. * <tt>done</tt> method. For clarity, all inner class support 142. * methods are same as outer, prefixed with "inner". 143. * 144. * Uses AQS sync state to represent run status 145. */ 146. private final class Sync extends AbstractQueuedSynchronizer { 147. /** State value representing that task is running */ 148. private static final int RUNNING = 1; 149. /** State value representing that task ran */ 150. private static final int RAN = 2; 151. /** State value representing that task was cancelled */ 152. private static final int CANCELLED = 4; 153. 154. /** The underlying callable */ 155. private final Callable<V> callable; 156. /** The result to return from get() */ 157. private V result; 158. /** The exception to throw from get() */ 159. private Throwable exception; 160. 161. /** 162. * The thread running task. When nulled after set/cancel, this 163. * indicates that the results are accessible. Must be 164. * volatile, to ensure visibility upon completion. 165. */ 166. private volatile Thread runner; 167. 168. Sync(Callable<V> callable) { 169. this.callable = callable; 170. } 171. 172. private boolean ranOrCancelled(int state) { 173. return (state & (RAN | CANCELLED)) != 0; 174. } 175. 176. /** 177. * Implements AQS base acquire to succeed if ran or cancelled 178. */ 179. protected int tryAcquireShared(int ignore) { 180. return innerIsDone()? 1 : -1; 181. } 182. 183. /** 184. * Implements AQS base release to always signal after setting 185. * final done status by nulling runner thread. 186. */ 187. protected boolean tryReleaseShared(int ignore) { 188. runner = null; 189. return true; 190. } 191. 192. boolean innerIsCancelled() { 193. return getState() == CANCELLED; 194. } 195. 196. boolean innerIsDone() { 197. return ranOrCancelled(getState()) && runner == null; 198. } 199. 200. V innerGet() throws InterruptedException, ExecutionException { 201. acquireSharedInterruptibly(0); 202. if (getState() == CANCELLED) 203. throw new CancellationException(); 204. if (exception != null) 205. throw new ExecutionException(exception); 206. return result; 207. } 208. 209. V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { 210. if (!tryAcquireSharedNanos(0, nanosTimeout)) 211. throw new TimeoutException(); 212. if (getState() == CANCELLED) 213. throw new CancellationException(); 214. if (exception != null) 215. throw new ExecutionException(exception); 216. return result; 217. } 218. 219. void innerSet(V v) { 220. for (;;) { 221. int s = getState(); 222. if (ranOrCancelled(s)) 223. return; 224. if (compareAndSetState(s, RAN)) 225. break; 226. } 227. result = v; 228. releaseShared(0); 229. done(); 230. } 231. 232. void innerSetException(Throwable t) { 233. for (;;) { 234. int s = getState(); 235. if (ranOrCancelled(s)) 236. return; 237. if (compareAndSetState(s, RAN)) 238. break; 239. } 240. exception = t; 241. result = null; 242. releaseShared(0); 243. done(); 244. } 245. 246. boolean innerCancel(boolean mayInterruptIfRunning) { 247. for (;;) { 248. int s = getState(); 249. if (ranOrCancelled(s)) 250. return false; 251. if (compareAndSetState(s, CANCELLED)) 252. break; 253. } 254. if (mayInterruptIfRunning) { 255. Thread r = runner; 256. if (r != null) 257. r.interrupt(); 258. } 259. releaseShared(0); 260. done(); 261. return true; 262. } 263. 264. void innerRun() { 265. if (!compareAndSetState(0, RUNNING)) 266. return; 267. try { 268. runner = Thread.currentThread(); 269. innerSet(callable.call()); 270. } catch(Throwable ex) { 271. innerSetException(ex); 272. } 273. } 274. 275. boolean innerRunAndReset() { 276. if (!compareAndSetState(0, RUNNING)) 277. return false; 278. try { 279. runner = Thread.currentThread(); 280. callable.call(); // don't set result 281. runner = null; 282. return compareAndSetState(RUNNING, 0); 283. } catch(Throwable ex) { 284. innerSetException(ex); 285. return false; 286. } 287. } 288. } 289.}
import java.util.concurrent.FutureTask; public class FutureCallableDemo { public static long fibonacci(long n) { if(n <=1) { return n; } else { return fibonacci(n-1) + fibonacci(n-2); } } /** * @param args */ public static void main(String[] args) { class Result { private long result; } final Result r = new Result(); FutureTask<Result> fib30 = new FutureTask<>( new Runnable() { @Override public void run() { r.result = fibonacci(30); }
主程序要监控线程运行状态, 当线程执行完后, 再读 result.
35. /** Synchronization control for FutureTask */
36. private final Sync sync;
37.
38. /**
39. * Creates a <tt>FutureTask</tt> that will upon running, execute the
40. * given <tt>Callable</tt>.
41. *
42. * @param callable the callable task
43. * @throws NullPointerException if callable is null
44. */
45. public FutureTask(Callable<V> callable) {
46. if (callable == null)
47. throw new NullPointerException();
48. sync = new Sync(callable);
49. }
50.
51. /**
52. * Creates a <tt>FutureTask</tt> that will upon running, execute the
53. * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
54. * given result on successful completion.
55. *
56. * @param runnable the runnable task
57. * @param result the result to return on successful completion. If
58. * you don't need a particular result, consider using
59. * constructions of the form:
60. * <tt>Future<?> f = new FutureTask<Object>(runnable, null)</tt>
61. * @throws NullPointerException if runnable is null
62. */
63. public FutureTask(Runnable runnable, V result) {
64. sync = new Sync(Executors.callable(runnable, result));
65. }
66.
67. public boolean isCancelled() {
68. return sync.innerIsCancelled();
69. }
70.
71. public boolean isDone() {
72. return sync.innerIsDone();
73. }
74.
75. public boolean cancel(boolean mayInterruptIfRunning) {
76. return sync.innerCancel(mayInterruptIfRunning);
77. }
78.
79. public V get() throws InterruptedException, ExecutionException {
80. return sync.innerGet();
81. }
82.
83. public V get(long timeout, TimeUnit unit)
84. throws InterruptedException, ExecutionException, TimeoutException {
85. return sync.innerGet(unit.toNanos(timeout));
86. }
87.
88. /**
89. * Protected method invoked when this task transitions to state
90. * <tt>isDone</tt> (whether normally or via cancellation). The
91. * default implementation does nothing. Subclasses may override
92. * this method to invoke completion callbacks or perform
93. * bookkeeping. Note that you can query status inside the
94. * implementation of this method to determine whether this task
95. * has been cancelled.
96. */
97. protected void done() { }
98.
99. /**
100. * Sets the result of this Future to the given value unless
101. * this future has already been set or has been cancelled.
102. * @param v the value
103. */
104. protected void set(V v) {
105. sync.innerSet(v);
106. }
107.
108. /**
109. * Causes this future to report an <tt>ExecutionException</tt>
110. * with the given throwable as its cause, unless this Future has
111. * already been set or has been cancelled.
112. * @param t the cause of failure.
113. */
114. protected void setException(Throwable t) {
115. sync.innerSetException(t);
116. }
117.
118. /**
119. * Sets this Future to the result of computation unless
120. * it has been cancelled.
121. */
122. public void run() {
123. sync.innerRun();
124. }
125.
126. /**
127. * Executes the computation without setting its result, and then
128. * resets this Future to initial state, failing to do so if the
129. * computation encounters an exception or is cancelled. This is
130. * designed for use with tasks that intrinsically execute more
131. * than once.
132. * @return true if successfully run and reset
133. */
134. protected boolean runAndReset() {
135. return sync.innerRunAndReset();
136. }
137.
138. /**
139. * Synchronization control for FutureTask. Note that this must be
140. * a non-static inner class in order to invoke the protected
141. * <tt>done</tt> method. For clarity, all inner class support
142. * methods are same as outer, prefixed with "inner".
143. *
144. * Uses AQS sync state to represent run status
145. */
146. private final class Sync extends AbstractQueuedSynchronizer {
147. /** State value representing that task is running */
148. private static final int RUNNING = 1;
149. /** State value representing that task ran */
150. private static final int RAN = 2;
151. /** State value representing that task was cancelled */
152. private static final int CANCELLED = 4;
153.
154. /** The underlying callable */
155. private final Callable<V> callable;
156. /** The result to return from get() */
157. private V result;
158. /** The exception to throw from get() */
159. private Throwable exception;
160.
161. /**
162. * The thread running task. When nulled after set/cancel, this
163. * indicates that the results are accessible. Must be
164. * volatile, to ensure visibility upon completion.
165. */
166. private volatile Thread runner;
167.
168. Sync(Callable<V> callable) {
169. this.callable = callable;
170. }
171.
172. private boolean ranOrCancelled(int state) {
173. return (state & (RAN | CANCELLED)) != 0;
174. }
175.
176. /**
177. * Implements AQS base acquire to succeed if ran or cancelled
178. */
179. protected int tryAcquireShared(int ignore) {
180. return innerIsDone()? 1 : -1;
181. }
182.
183. /**
184. * Implements AQS base release to always signal after setting
185. * final done status by nulling runner thread.
186. */
187. protected boolean tryReleaseShared(int ignore) {
188. runner = null;
189. return true;
190. }
191.
192. boolean innerIsCancelled() {
193. return getState() == CANCELLED;
194. }
195.
196. boolean innerIsDone() {
197. return ranOrCancelled(getState()) && runner == null;
198. }
199.
200. V innerGet() throws InterruptedException, ExecutionException {
201. acquireSharedInterruptibly(0);
202. if (getState() == CANCELLED)
203. throw new CancellationException();
204. if (exception != null)
205. throw new ExecutionException(exception);
206. return result;
207. }
208.
209. V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
210. if (!tryAcquireSharedNanos(0, nanosTimeout))
211. throw new TimeoutException();
212. if (getState() == CANCELLED)
213. throw new CancellationException();
214. if (exception != null)
215. throw new ExecutionException(exception);
216. return result;
217. }
218.
219. void innerSet(V v) {
220. for (;;) {
221. int s = getState();
222. if (ranOrCancelled(s))
223. return;
224. if (compareAndSetState(s, RAN))
225. break;
226. }
227. result = v;
228. releaseShared(0);
229. done();
230. }
231.
232. void innerSetException(Throwable t) {
233. for (;;) {
234. int s = getState();
235. if (ranOrCancelled(s))
236. return;
237. if (compareAndSetState(s, RAN))
238. break;
239. }
240. exception = t;
241. result = null;
242. releaseShared(0);
243. done();
244. }
245.
246. boolean innerCancel(boolean mayInterruptIfRunning) {
247. for (;;) {
248. int s = getState();
249. if (ranOrCancelled(s))
250. return false;
251. if (compareAndSetState(s, CANCELLED))
252. break;
253. }
254. if (mayInterruptIfRunning) {
255. Thread r = runner;
256. if (r != null)
257. r.interrupt();
258. }
259. releaseShared(0);
260. done();
261. return true;
262. }
263.
264. void innerRun() {
265. if (!compareAndSetState(0, RUNNING))
266. return;
267. try {
268. runner = Thread.currentThread();
269. innerSet(callable.call());
270. } catch(Throwable ex) {
271. innerSetException(ex);
272. }
273. }
274.
275. boolean innerRunAndReset() {
276. if (!compareAndSetState(0, RUNNING))
277. return false;
278. try {
279. runner = Thread.currentThread();
280. callable.call(); // don't set result
281. runner = null;
282. return compareAndSetState(RUNNING, 0);
283. } catch(Throwable ex) {
284. innerSetException(ex);
285. return false;
286. }
287. }
288. }
289.}
public class FutureCallableDemo {
public static long fibonacci(long n) {
if(n <=1) {
return n;
} else {
return fibonacci(n-1) + fibonacci(n-2);
}
}
/**
* @param args
*/
public static void main(String[] args) {
class Result {
private long result;
}
final Result r = new Result();
FutureTask<Result> fib30 = new FutureTask<>(
new Runnable() {
@Override
public void run() {
r.result = fibonacci(30);
}
}
, r);
System.out.println("老闆,我要第30個費式數,待會來拿...");
new Thread(fib30).start();
System.out.println("忙別的事去...");
try {
Thread.sleep(5000);
System.out.printf("第30個費式數:%d%n", fib30.get().result);
} catch(Exception ex) {
ex.printStackTrace();
}
}}