ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FutureTaskCancelLoops.java
Revision: 1.1
Committed: Thu Jun 16 09:53:45 2011 UTC (12 years, 10 months ago) by jsr166
Branch: MAIN
Log Message:
demonstrate leaked interrupt

File Contents

# Content
1 /*
2 * Written by Doug Lea and Martin Buchholz with assistance from members of
3 * JCP JSR-166 Expert Group and released to the public domain, as explained
4 * at http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 import java.util.concurrent.*;
8 import java.util.concurrent.atomic.*;
9
10 /**
11 * Tries to demonstrate a leaked interrupt.
12 */
13 public class FutureTaskCancelLoops {
14 static final AtomicLong count = new AtomicLong(0);
15
16 static volatile Future<?> cancelMe = null;
17
18 static volatile boolean leakedInterrupt = false;
19
20 static class InterruptMeTask extends FutureTask<Void> {
21 static class InterruptMe implements Runnable {
22 volatile Future<?> myFuture;
23
24 public void run() {
25 assert myFuture != null;
26 if (cancelMe != null) {
27 // We're likely to get the interrupt meant for previous task.
28 // Clear interrupts first to prove *we* got interrupted.
29 Thread.interrupted();
30 while (cancelMe != null && !leakedInterrupt) {
31 if (Thread.interrupted()) {
32 leakedInterrupt = true;
33 System.err.println("leaked interrupt!");
34 }
35 }
36 } else {
37 cancelMe = myFuture;
38 do {} while (! myFuture.isCancelled() && !leakedInterrupt);
39 }
40 count.getAndIncrement();
41 }
42 }
43 InterruptMeTask() { this(new InterruptMe()); }
44 InterruptMeTask(InterruptMe r) {
45 super(r, null);
46 r.myFuture = this;
47 }
48 }
49
50 static long millisElapsedSince(long startTimeNanos) {
51 return (System.nanoTime() - startTimeNanos)/(1000L*1000L);
52 }
53
54 public static void main(String[] args) throws Exception {
55 long startTime = System.nanoTime();
56 final ThreadPoolExecutor pool =
57 new ThreadPoolExecutor(1, 1,
58 0L, TimeUnit.MILLISECONDS,
59 new LinkedBlockingQueue<Runnable>(10000));
60
61 final Thread cancelBot = new Thread(new Runnable() {
62 public void run() {
63 while (!leakedInterrupt) {
64 Future<?> future = cancelMe;
65 if (future != null) {
66 future.cancel(true);
67 cancelMe = null;
68 }}}});
69 cancelBot.setDaemon(true);
70 cancelBot.start();
71
72 while (!leakedInterrupt && millisElapsedSince(startTime) < 1000L) {
73 try {
74 pool.execute(new InterruptMeTask());
75 } catch (RejectedExecutionException ree) {
76 Thread.sleep(1);
77 }
78 }
79 pool.shutdownNow();
80 if (leakedInterrupt) {
81 String msg = String.format
82 ("%d tasks run, %d millis elapsed, till leaked interrupt%n",
83 count.get(), millisElapsedSince(startTime));
84 throw new IllegalStateException(msg);
85 } else {
86 System.out.printf
87 ("%d tasks run, %d millis elapsed%n",
88 count.get(), millisElapsedSince(startTime));
89 }
90 }
91 }