Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java
+++ new/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java
1 1 /*
2 2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation.
8 8 *
9 9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 * version 2 for more details (a copy is included in the LICENSE file that
13 13 * accompanied this code).
14 14 *
15 15 * You should have received a copy of the GNU General Public License version
16 16 * 2 along with this work; if not, write to the Free Software Foundation,
17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 *
19 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 20 * or visit www.oracle.com if you need additional information or have any
21 21 * questions.
22 22 */
23 23
24 24 /*
25 25 * @test
26 26 * @bug 6431315
27 27 * @summary ExecutorService.invokeAll might hang
28 28 * @author Martin Buchholz
29 29 */
30 30
31 31 import java.util.*;
32 32 import java.util.concurrent.*;
33 33
34 34 /**
35 35 * Adapted from Doug Lea, which was...
36 36 * adapted from a posting by Tom Sugden tom at epcc.ed.ac.uk
37 37 */
38 38 public class BlockingTaskExecutor {
39 39
40 40 static void realMain(String[] args) throws Throwable {
41 41 for (int i = 1; i <= 100; i++) {
42 42 System.out.print(".");
43 43 test();
44 44 }
45 45 }
46 46
47 47 static void test() throws Throwable {
48 48 final ExecutorService executor = Executors.newCachedThreadPool();
49 49
50 50 final NotificationReceiver notifiee1 = new NotificationReceiver();
51 51 final NotificationReceiver notifiee2 = new NotificationReceiver();
52 52
53 53 final Collection<Callable<Object>> tasks =
54 54 new ArrayList<Callable<Object>>();
55 55 tasks.add(new BlockingTask(notifiee1));
56 56 tasks.add(new BlockingTask(notifiee2));
57 57 tasks.add(new NonBlockingTask());
58 58
59 59 // start a thread to invoke the tasks
60 60 Thread thread = new Thread() { public void run() {
61 61 try { executor.invokeAll(tasks); }
62 62 catch (RejectedExecutionException t) {/* OK */}
63 63 catch (Throwable t) { unexpected(t); }}};
64 64 thread.start();
65 65
66 66 // Wait until tasks begin execution
67 67 notifiee1.waitForNotification();
68 68 notifiee2.waitForNotification();
69 69
70 70 // Now try to shutdown the executor service while tasks
71 71 // are blocked. This should cause the tasks to be
72 72 // interrupted.
73 73 executor.shutdownNow();
74 74 if (! executor.awaitTermination(5, TimeUnit.SECONDS))
75 75 throw new Error("Executor stuck");
76 76
77 77 // Wait for the invocation thread to complete.
78 78 thread.join(1000);
79 79 if (thread.isAlive()) {
↓ open down ↓ |
79 lines elided |
↑ open up ↑ |
80 80 thread.interrupt();
81 81 thread.join(1000);
82 82 throw new Error("invokeAll stuck");
83 83 }
84 84 }
85 85
86 86 /**
87 87 * A helper class with a method to wait for a notification.
88 88 *
89 89 * The notification is received via the
90 - * <code>sendNotification</code> method.
90 + * {@code sendNotification} method.
91 91 */
92 92 static class NotificationReceiver {
93 93 /** Has the notifiee been notified? */
94 94 boolean notified = false;
95 95
96 96 /**
97 97 * Notify the notification receiver.
98 98 */
99 99 public synchronized void sendNotification() {
100 100 notified = true;
101 101 notifyAll();
102 102 }
103 103
104 104 /**
105 105 * Waits until a notification has been received.
106 106 *
107 107 * @throws InterruptedException if the wait is interrupted
108 108 */
109 109 public synchronized void waitForNotification()
110 110 throws InterruptedException {
111 111 while (! notified)
112 112 wait();
113 113 }
114 114 }
115 115
116 116 /**
117 117 * A callable task that blocks until it is interrupted.
118 118 * This task sends a notification to a notification receiver when
119 119 * it is first called.
120 120 */
121 121 static class BlockingTask implements Callable<Object> {
122 122 private final NotificationReceiver notifiee;
123 123
124 124 BlockingTask(NotificationReceiver notifiee) {
125 125 this.notifiee = notifiee;
126 126 }
127 127
128 128 public Object call() throws InterruptedException {
129 129 notifiee.sendNotification();
130 130
131 131 // wait indefinitely until task is interrupted
132 132 while (true) {
133 133 synchronized (this) {
134 134 wait();
135 135 }
136 136 }
137 137 }
138 138 }
139 139
140 140 /**
141 141 * A callable task that simply returns a string result.
142 142 */
143 143 static class NonBlockingTask implements Callable<Object> {
144 144 public Object call() {
145 145 return "NonBlockingTaskResult";
146 146 }
147 147 }
148 148
149 149 //--------------------- Infrastructure ---------------------------
150 150 static volatile int passed = 0, failed = 0;
151 151 static void pass() {passed++;}
152 152 static void fail() {failed++; Thread.dumpStack();}
153 153 static void fail(String msg) {System.out.println(msg); fail();}
154 154 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
155 155 static void check(boolean cond) {if (cond) pass(); else fail();}
156 156 static void equal(Object x, Object y) {
157 157 if (x == null ? y == null : x.equals(y)) pass();
158 158 else fail(x + " not equal to " + y);}
159 159 public static void main(String[] args) throws Throwable {
160 160 try {realMain(args);} catch (Throwable t) {unexpected(t);}
161 161 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
162 162 if (failed > 0) throw new AssertionError("Some tests failed");}
163 163 }
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX