ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.7
Committed: Sun Oct 5 23:00:40 2003 UTC (20 years, 6 months ago) by dl
Branch: MAIN
Changes since 1.6: +13 -13 lines
Log Message:
Added tests and documentation

File Contents

# Content
1 /*
2 * Written by members of JCP JSR-166 Expert Group and released to the
3 * public domain. Use, modify, and redistribute this code in any way
4 * without acknowledgement. Other contributors include Andrew Wright,
5 * Jeffrey Hayes, Pat Fischer, Mike Judd.
6 */
7
8
9 import junit.framework.*;
10 import java.util.*;
11 import java.util.concurrent.*;
12 import java.math.BigInteger;
13
14 public class ExecutorsTest extends JSR166TestCase{
15 public static void main(String[] args) {
16 junit.textui.TestRunner.run (suite());
17 }
18 public static Test suite() {
19 return new TestSuite(ExecutorsTest.class);
20 }
21
22 private static final String TEST_STRING = "a test string";
23
24 private static class StringTask implements Callable<String> {
25 public String call() { return TEST_STRING; }
26 }
27
28 static class DirectExecutor implements Executor {
29 public void execute(Runnable r) {
30 r.run();
31 }
32 }
33
34 static class TimedCallable<T> implements Callable<T> {
35 private final Executor exec;
36 private final Callable<T> func;
37 private final long msecs;
38
39 TimedCallable(Executor exec, Callable<T> func, long msecs) {
40 this.exec = exec;
41 this.func = func;
42 this.msecs = msecs;
43 }
44
45 public T call() throws Exception {
46 Future<T> ftask = Executors.execute(exec, func);
47 try {
48 return ftask.get(msecs, TimeUnit.MILLISECONDS);
49 } finally {
50 ftask.cancel(true);
51 }
52 }
53 }
54
55
56 private static class Fib implements Callable<BigInteger> {
57 private final BigInteger n;
58 Fib(long n) {
59 if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n);
60 this.n = BigInteger.valueOf(n);
61 }
62 public BigInteger call() {
63 BigInteger f1 = BigInteger.ONE;
64 BigInteger f2 = f1;
65 for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
66 BigInteger t = f1.add(f2);
67 f1 = f2;
68 f2 = t;
69 }
70 return f1;
71 }
72 };
73
74 /**
75 * A newCachedThreadPool can execute runnables
76 */
77 public void testNewCachedThreadPool1() {
78 ExecutorService e = Executors.newCachedThreadPool();
79 e.execute(new NoOpRunnable());
80 e.execute(new NoOpRunnable());
81 e.execute(new NoOpRunnable());
82 e.shutdown();
83 }
84
85 /**
86 * A newCachedThreadPool with given ThreadFactory can execute runnables
87 */
88 public void testNewCachedThreadPool2() {
89 ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
90 e.execute(new NoOpRunnable());
91 e.execute(new NoOpRunnable());
92 e.execute(new NoOpRunnable());
93 e.shutdown();
94 }
95
96 /**
97 * A newCachedThreadPool with null ThreadFactory throws NPE
98 */
99 public void testNewCachedThreadPool3() {
100 try {
101 ExecutorService e = Executors.newCachedThreadPool(null);
102 shouldThrow();
103 }
104 catch(NullPointerException success) {
105 }
106 }
107
108
109 /**
110 * A new SingleThreadExecutor can execute runnables
111 */
112 public void testNewSingleThreadExecutor1() {
113 ExecutorService e = Executors.newSingleThreadExecutor();
114 e.execute(new NoOpRunnable());
115 e.execute(new NoOpRunnable());
116 e.execute(new NoOpRunnable());
117 e.shutdown();
118 }
119
120 /**
121 * A new SingleThreadExecutor with given ThreadFactory can execute runnables
122 */
123 public void testNewSingleThreadExecutor2() {
124 ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
125 e.execute(new NoOpRunnable());
126 e.execute(new NoOpRunnable());
127 e.execute(new NoOpRunnable());
128 e.shutdown();
129 }
130
131 /**
132 * A new SingleThreadExecutor with null ThreadFactory throws NPE
133 */
134 public void testNewSingleThreadExecutor3() {
135 try {
136 ExecutorService e = Executors.newSingleThreadExecutor(null);
137 shouldThrow();
138 }
139 catch(NullPointerException success) {
140 }
141 }
142
143 /**
144 * A new newFixedThreadPool can execute runnables
145 */
146 public void testNewFixedThreadPool1() {
147 ExecutorService e = Executors.newFixedThreadPool(2);
148 e.execute(new NoOpRunnable());
149 e.execute(new NoOpRunnable());
150 e.execute(new NoOpRunnable());
151 e.shutdown();
152 }
153
154 /**
155 * A new newFixedThreadPool with given ThreadFactory can execute runnables
156 */
157 public void testNewFixedThreadPool2() {
158 ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
159 e.execute(new NoOpRunnable());
160 e.execute(new NoOpRunnable());
161 e.execute(new NoOpRunnable());
162 e.shutdown();
163 }
164
165 /**
166 * A new newFixedThreadPool with null ThreadFactory throws NPE
167 */
168 public void testNewFixedThreadPool3() {
169 try {
170 ExecutorService e = Executors.newFixedThreadPool(2, null);
171 shouldThrow();
172 }
173 catch(NullPointerException success) {
174 }
175 }
176
177 /**
178 * A new newFixedThreadPool with 0 threads throws IAE
179 */
180 public void testNewFixedThreadPool4() {
181 try {
182 ExecutorService e = Executors.newFixedThreadPool(0);
183 shouldThrow();
184 }
185 catch(IllegalArgumentException success) {
186 }
187 }
188
189 /**
190 * execute of runnable runs it to completion
191 */
192 public void testExecuteRunnable() {
193 try {
194 Executor e = new DirectExecutor();
195 TrackedShortRunnable task = new TrackedShortRunnable();
196 assertFalse(task.done);
197 Future<String> future = Executors.execute(e, task, TEST_STRING);
198 String result = future.get();
199 assertTrue(task.done);
200 assertSame(TEST_STRING, result);
201 }
202 catch (ExecutionException ex) {
203 unexpectedException();
204 }
205 catch (InterruptedException ex) {
206 unexpectedException();
207 }
208 }
209
210 /**
211 * invoke of a runnable runs it to completion
212 */
213 public void testInvokeRunnable() {
214 try {
215 Executor e = new DirectExecutor();
216 TrackedShortRunnable task = new TrackedShortRunnable();
217 assertFalse(task.done);
218 Executors.invoke(e, task);
219 assertTrue(task.done);
220 }
221 catch (ExecutionException ex) {
222 unexpectedException();
223 }
224 catch (InterruptedException ex) {
225 unexpectedException();
226 }
227 }
228
229 /**
230 * execute of a callable runs it to completion
231 */
232 public void testExecuteCallable() {
233 try {
234 Executor e = new DirectExecutor();
235 Future<String> future = Executors.execute(e, new StringTask());
236 String result = future.get();
237 assertSame(TEST_STRING, result);
238 }
239 catch (ExecutionException ex) {
240 unexpectedException();
241 }
242 catch (InterruptedException ex) {
243 unexpectedException();
244 }
245 }
246
247 /**
248 * invoke of a collable runs it to completion
249 */
250 public void testInvokeCallable() {
251 try {
252 Executor e = new DirectExecutor();
253 String result = Executors.invoke(e, new StringTask());
254
255 assertSame(TEST_STRING, result);
256 }
257 catch (ExecutionException ex) {
258 unexpectedException();
259 }
260 catch (InterruptedException ex) {
261 unexpectedException();
262 }
263 }
264
265 /**
266 * execute with null executor throws NPE
267 */
268 public void testNullExecuteRunnable() {
269 try {
270 TrackedShortRunnable task = new TrackedShortRunnable();
271 assertFalse(task.done);
272 Future<String> future = Executors.execute(null, task, TEST_STRING);
273 shouldThrow();
274 }
275 catch (NullPointerException success) {
276 }
277 catch (Exception ex) {
278 unexpectedException();
279 }
280 }
281
282 /**
283 * execute with a null runnable throws NPE
284 */
285 public void testExecuteNullRunnable() {
286 try {
287 Executor e = new DirectExecutor();
288 TrackedShortRunnable task = null;
289 Future<String> future = Executors.execute(e, task, TEST_STRING);
290 shouldThrow();
291 }
292 catch (NullPointerException success) {
293 }
294 catch (Exception ex) {
295 unexpectedException();
296 }
297 }
298
299 /**
300 * invoke of a null runnable throws NPE
301 */
302 public void testInvokeNullRunnable() {
303 try {
304 Executor e = new DirectExecutor();
305 TrackedShortRunnable task = null;
306 Executors.invoke(e, task);
307 shouldThrow();
308 }
309 catch (NullPointerException success) {
310 }
311 catch (Exception ex) {
312 unexpectedException();
313 }
314 }
315
316 /**
317 * execute of a null callable throws NPE
318 */
319 public void testExecuteNullCallable() {
320 try {
321 Executor e = new DirectExecutor();
322 StringTask t = null;
323 Future<String> future = Executors.execute(e, t);
324 shouldThrow();
325 }
326 catch (NullPointerException success) {
327 }
328 catch (Exception ex) {
329 unexpectedException();
330 }
331 }
332
333 /**
334 * invoke of a null callable throws NPE
335 */
336 public void testInvokeNullCallable() {
337 try {
338 Executor e = new DirectExecutor();
339 StringTask t = null;
340 String result = Executors.invoke(e, t);
341 shouldThrow();
342 }
343 catch (NullPointerException success) {
344 }
345 catch (Exception ex) {
346 unexpectedException();
347 }
348 }
349
350 /**
351 * execute(Executor, Runnable) throws RejectedExecutionException
352 * if saturated.
353 */
354 public void testExecute1() {
355 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
356 try {
357
358 for(int i = 0; i < 5; ++i){
359 Executors.execute(p, new MediumRunnable(), Boolean.TRUE);
360 }
361 shouldThrow();
362 } catch(RejectedExecutionException success){}
363 joinPool(p);
364 }
365
366 /**
367 * execute(Executor, Callable)throws RejectedExecutionException
368 * if saturated.
369 */
370 public void testExecute2() {
371 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
372 try {
373 for(int i = 0; i < 5; ++i) {
374 Executors.execute(p, new SmallCallable());
375 }
376 shouldThrow();
377 } catch(RejectedExecutionException e){}
378 joinPool(p);
379 }
380
381
382 /**
383 * invoke(Executor, Runnable) throws InterruptedException if
384 * caller interrupted.
385 */
386 public void testInterruptedInvoke() {
387 final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
388 Thread t = new Thread(new Runnable() {
389 public void run() {
390 try {
391 Executors.invoke(p,new Runnable() {
392 public void run() {
393 try {
394 Thread.sleep(MEDIUM_DELAY_MS);
395 shouldThrow();
396 } catch(InterruptedException e){
397 }
398 }
399 });
400 } catch(InterruptedException success){
401 } catch(Exception e) {
402 unexpectedException();
403 }
404
405 }
406 });
407 try {
408 t.start();
409 Thread.sleep(SHORT_DELAY_MS);
410 t.interrupt();
411 } catch(Exception e){
412 unexpectedException();
413 }
414 joinPool(p);
415 }
416
417 /**
418 * invoke(Executor, Runnable) throws ExecutionException if
419 * runnable throws exception.
420 */
421 public void testInvoke3() {
422 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
423 try {
424 Runnable r = new Runnable() {
425 public void run() {
426 int i = 5/0;
427 }
428 };
429
430 for(int i =0; i < 5; i++){
431 Executors.invoke(p,r);
432 }
433
434 shouldThrow();
435 } catch(ExecutionException success){
436 } catch(Exception e){
437 unexpectedException();
438 }
439 joinPool(p);
440 }
441
442
443
444 /**
445 * invoke(Executor, Callable) throws InterruptedException if
446 * callable throws exception
447 */
448 public void testInvoke5() {
449 final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
450
451 final Callable c = new Callable() {
452 public Object call() {
453 try {
454 Executors.invoke(p, new SmallCallable());
455 shouldThrow();
456 } catch(InterruptedException e){}
457 catch(RejectedExecutionException e2){}
458 catch(ExecutionException e3){}
459 return Boolean.TRUE;
460 }
461 };
462
463
464
465 Thread t = new Thread(new Runnable() {
466 public void run() {
467 try {
468 c.call();
469 } catch(Exception e){}
470 }
471 });
472 try {
473 t.start();
474 Thread.sleep(SHORT_DELAY_MS);
475 t.interrupt();
476 t.join();
477 } catch(InterruptedException e){
478 unexpectedException();
479 }
480
481 joinPool(p);
482 }
483
484 /**
485 * invoke(Executor, Callable) will throw ExecutionException
486 * if callable throws exception
487 */
488 public void testInvoke6() {
489 ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
490
491 try {
492 Callable c = new Callable() {
493 public Object call() {
494 int i = 5/0;
495 return Boolean.TRUE;
496 }
497 };
498
499 for(int i =0; i < 5; i++){
500 Executors.invoke(p,c);
501 }
502
503 shouldThrow();
504 }
505 catch(ExecutionException success){
506 } catch(Exception e) {
507 unexpectedException();
508 }
509 joinPool(p);
510 }
511
512
513
514 /**
515 * timeouts from execute will time out if they compute too long.
516 */
517 public void testTimedCallable() {
518 int N = 10000;
519 ExecutorService executor = Executors.newSingleThreadExecutor();
520 List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
521 try {
522 long startTime = System.currentTimeMillis();
523
524 long i = 0;
525 while (tasks.size() < N) {
526 tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
527 i += 10;
528 }
529
530 int iters = 0;
531 BigInteger sum = BigInteger.ZERO;
532 for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
533 try {
534 ++iters;
535 sum = sum.add(it.next().call());
536 }
537 catch (TimeoutException success) {
538 assertTrue(iters > 0);
539 return;
540 }
541 catch (Exception e) {
542 unexpectedException();
543 }
544 }
545 // if by chance we didn't ever time out, total time must be small
546 long elapsed = System.currentTimeMillis() - startTime;
547 assertTrue(elapsed < N);
548 }
549 finally {
550 joinPool(executor);
551 }
552 }
553
554
555
556
557 }