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

# User Rev Content
1 jsr166 1.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     }