6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 5014783 27 * @summary Basic unit test of thread states returned by 28 * Thread.getState(). 29 * 30 * @author Mandy Chung 31 * 32 * @build ThreadStateTest 33 * @run main ThreadStateTest 34 */ 35 36 import java.util.concurrent.locks.LockSupport; 37 import java.util.concurrent.Phaser; 38 39 public class ThreadStateTest { 40 // maximum number of retries when checking for thread state. 41 static final int MAX_RETRY = 500; 42 43 private static boolean testFailed = false; 44 45 // used to achieve waiting states 46 static final Object globalLock = new Object(); 47 48 public static void main(String[] argv) { 49 // Call Thread.getState to force all initialization done 50 // before test verification begins. 51 Thread.currentThread().getState(); 52 MyThread myThread = new MyThread("MyThread"); 53 54 // before myThread starts 55 checkThreadState(myThread, Thread.State.NEW); 56 57 myThread.start(); 58 myThread.waitUntilStarted(); 59 checkThreadState(myThread, Thread.State.RUNNABLE); 60 61 synchronized (globalLock) { 62 myThread.goBlocked(); 63 checkThreadState(myThread, Thread.State.BLOCKED); 64 } 65 66 myThread.goWaiting(); 67 checkThreadState(myThread, Thread.State.WAITING); 68 69 myThread.goTimedWaiting(); 70 checkThreadState(myThread, Thread.State.TIMED_WAITING); 71 72 86 87 myThread.goSleeping(); 88 checkThreadState(myThread, Thread.State.TIMED_WAITING); 89 90 myThread.terminate(); 91 checkThreadState(myThread, Thread.State.TERMINATED); 92 93 try { 94 myThread.join(); 95 } catch (InterruptedException e) { 96 e.printStackTrace(); 97 System.out.println("Unexpected exception."); 98 testFailed = true; 99 } 100 101 if (testFailed) 102 throw new RuntimeException("TEST FAILED."); 103 System.out.println("Test passed."); 104 } 105 106 private static void checkThreadState(Thread t, Thread.State expected) { 107 // wait for the thread to transition to the expected state. 108 // There is a small window between the thread checking the state 109 // and the thread actual entering that state. 110 Thread.State state; 111 int retryCount=0; 112 while ((state = t.getState()) != expected && retryCount < MAX_RETRY) { 113 if (state != Thread.State.RUNNABLE) { 114 throw new RuntimeException("Thread not in expected state yet," + 115 " but it should at least be RUNNABLE"); 116 } 117 goSleep(10); 118 retryCount++; 119 } 120 121 System.out.println("Checking thread state " + state); 122 if (state == null) { 123 throw new RuntimeException(t.getName() + " expected to have " + 124 expected + " but got null."); 125 } 126 127 if (state != expected) { 128 throw new RuntimeException(t.getName() + " expected to have " + 129 expected + " but got " + state); 130 } 131 } 132 133 private static void goSleep(long ms) { 134 try { 135 Thread.sleep(ms); 136 } catch (InterruptedException e) { 137 e.printStackTrace(); 138 System.out.println("Unexpected exception."); 139 testFailed = true; 140 } 141 } 142 143 static class MyThread extends Thread { 144 // Phaser to sync between the main thread putting 145 // this thread into various states 146 private Phaser phaser = new Phaser(2); 147 148 MyThread(String name) { 149 super(name); 150 } 151 152 private final int RUNNABLE = 0; 153 private final int BLOCKED = 1; 154 private final int WAITING = 2; 155 private final int TIMED_WAITING = 3; 156 private final int PARKED = 4; 157 private final int TIMED_PARKED = 5; 158 private final int SLEEPING = 6; 159 private final int TERMINATE = 7; 160 161 private volatile int state = RUNNABLE; 162 163 private boolean done = false; 164 public void run() { 165 // Signal main thread to continue. 166 phaser.arriveAndAwaitAdvance(); 167 168 while (!done) { 169 switch (state) { 170 case RUNNABLE: { 171 double sum = 0; 172 for (int i = 0; i < 1000; i++) { 173 double r = Math.random(); 174 double x = Math.pow(3, r); 175 sum += x - r; 176 } 177 break; 178 } 179 case BLOCKED: { 180 // signal main thread. 181 phaser.arrive(); 182 System.out.println(" myThread is going to block."); 183 synchronized (globalLock) { 184 // finish blocking 185 state = RUNNABLE; 186 } 187 break; 188 } 189 case WAITING: { 190 synchronized (globalLock) { 191 // signal main thread. 192 phaser.arrive(); 193 System.out.println(" myThread is going to wait."); 194 try { 195 globalLock.wait(); 196 } catch (InterruptedException e) { 197 // ignore 198 } 199 } 200 break; 201 } 202 case TIMED_WAITING: { 203 synchronized (globalLock) { 204 // signal main thread. 205 phaser.arrive(); 206 System.out.println(" myThread is going to timed wait."); 207 try { 208 globalLock.wait(10000); 209 } catch (InterruptedException e) { 210 // ignore 211 } 212 } 213 break; 214 } 215 case PARKED: { 216 // signal main thread. 217 phaser.arrive(); 218 System.out.println(" myThread is going to park."); 219 LockSupport.park(); 220 // give a chance for the main thread to block 221 goSleep(10); 222 break; 223 } 224 case TIMED_PARKED: { 225 // signal main thread. 226 phaser.arrive(); 227 System.out.println(" myThread is going to timed park."); 228 long deadline = System.currentTimeMillis() + 10000*1000; 229 LockSupport.parkUntil(deadline); 230 320 case WAITING: 321 case TIMED_WAITING: 322 state = newState; 323 synchronized (globalLock) { 324 globalLock.notify(); 325 } 326 break; 327 case PARKED: 328 case TIMED_PARKED: 329 state = newState; 330 LockSupport.unpark(this); 331 break; 332 case SLEEPING: 333 state = newState; 334 this.interrupt(); 335 break; 336 default: 337 state = newState; 338 break; 339 } 340 } 341 } 342 } | 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 5014783 8022208 27 * @summary Basic unit test of thread states returned by 28 * Thread.getState(). 29 * 30 * @author Mandy Chung 31 * 32 * @build ThreadStateTest 33 * @run main ThreadStateTest 34 */ 35 36 import java.util.concurrent.locks.LockSupport; 37 import java.util.concurrent.Phaser; 38 39 public class ThreadStateTest { 40 // maximum number of retries when checking for thread state. 41 private static final int MAX_RETRY = 500; 42 43 private static boolean testFailed = false; 44 45 // used to achieve waiting states 46 static final Object globalLock = new Object(); 47 48 public static void main(String[] argv) { 49 // Call Thread.getState to force all initialization done 50 // before test verification begins. 51 Thread.currentThread().getState(); 52 MyThread myThread = new MyThread("MyThread"); 53 myThread.setDaemon(true); 54 55 // before myThread starts 56 checkThreadState(myThread, Thread.State.NEW); 57 58 myThread.start(); 59 myThread.waitUntilStarted(); 60 checkThreadState(myThread, Thread.State.RUNNABLE); 61 62 synchronized (globalLock) { 63 myThread.goBlocked(); 64 checkThreadState(myThread, Thread.State.BLOCKED); 65 } 66 67 myThread.goWaiting(); 68 checkThreadState(myThread, Thread.State.WAITING); 69 70 myThread.goTimedWaiting(); 71 checkThreadState(myThread, Thread.State.TIMED_WAITING); 72 73 87 88 myThread.goSleeping(); 89 checkThreadState(myThread, Thread.State.TIMED_WAITING); 90 91 myThread.terminate(); 92 checkThreadState(myThread, Thread.State.TERMINATED); 93 94 try { 95 myThread.join(); 96 } catch (InterruptedException e) { 97 e.printStackTrace(); 98 System.out.println("Unexpected exception."); 99 testFailed = true; 100 } 101 102 if (testFailed) 103 throw new RuntimeException("TEST FAILED."); 104 System.out.println("Test passed."); 105 } 106 107 private static void checkThreadState(MyThread t, Thread.State expected) { 108 // wait for the thread to transition to the expected state. 109 // There is a small window between the thread checking the state 110 // and the thread actual entering that state. 111 Thread.State state; 112 int retryCount=0; 113 while ((state = t.getState()) != expected && retryCount < MAX_RETRY) { 114 goSleep(10); 115 retryCount++; 116 } 117 118 if (state == null) { 119 throw new RuntimeException(t.getName() + " expected to have " + 120 expected + " but got null."); 121 } 122 123 if (state != expected) { 124 throw new RuntimeException(String.format("%s expected in %s state but got %s " + 125 "(iterations %d interrupted %d)%n", 126 t.getName(), expected, state, t.iterations, t.interrupted)); 127 } 128 } 129 130 private static void goSleep(long ms) { 131 try { 132 Thread.sleep(ms); 133 } catch (InterruptedException e) { 134 e.printStackTrace(); 135 System.out.println("Unexpected exception."); 136 testFailed = true; 137 } 138 } 139 140 static class MyThread extends Thread { 141 // Phaser to sync between the main thread putting 142 // this thread into various states 143 private Phaser phaser = new Phaser(2); 144 145 MyThread(String name) { 146 super(name); 147 } 148 149 private final int RUNNABLE = 0; 150 private final int BLOCKED = 1; 151 private final int WAITING = 2; 152 private final int TIMED_WAITING = 3; 153 private final int PARKED = 4; 154 private final int TIMED_PARKED = 5; 155 private final int SLEEPING = 6; 156 private final int TERMINATE = 7; 157 158 private volatile int state = RUNNABLE; 159 160 private boolean done = false; 161 volatile int iterations=0; 162 volatile int interrupted=0; 163 public void run() { 164 // Signal main thread to continue. 165 phaser.arriveAndAwaitAdvance(); 166 167 while (!done) { 168 iterations++; 169 switch (state) { 170 case RUNNABLE: { 171 double sum = 0; 172 for (int i = 0; i < 1000; i++) { 173 double r = Math.random(); 174 double x = Math.pow(3, r); 175 sum += x - r; 176 } 177 break; 178 } 179 case BLOCKED: { 180 // signal main thread. 181 phaser.arrive(); 182 System.out.println(" myThread is going to block."); 183 synchronized (globalLock) { 184 // finish blocking 185 state = RUNNABLE; 186 } 187 break; 188 } 189 case WAITING: { 190 synchronized (globalLock) { 191 // signal main thread. 192 phaser.arrive(); 193 System.out.println(" myThread is going to wait."); 194 try { 195 globalLock.wait(); 196 } catch (InterruptedException e) { 197 // ignore 198 interrupted++; 199 } 200 } 201 break; 202 } 203 case TIMED_WAITING: { 204 synchronized (globalLock) { 205 // signal main thread. 206 phaser.arrive(); 207 System.out.println(" myThread is going to timed wait."); 208 try { 209 globalLock.wait(10000); 210 } catch (InterruptedException e) { 211 // ignore 212 interrupted++; 213 } 214 } 215 break; 216 } 217 case PARKED: { 218 // signal main thread. 219 phaser.arrive(); 220 System.out.println(" myThread is going to park."); 221 LockSupport.park(); 222 // give a chance for the main thread to block 223 goSleep(10); 224 break; 225 } 226 case TIMED_PARKED: { 227 // signal main thread. 228 phaser.arrive(); 229 System.out.println(" myThread is going to timed park."); 230 long deadline = System.currentTimeMillis() + 10000*1000; 231 LockSupport.parkUntil(deadline); 232 322 case WAITING: 323 case TIMED_WAITING: 324 state = newState; 325 synchronized (globalLock) { 326 globalLock.notify(); 327 } 328 break; 329 case PARKED: 330 case TIMED_PARKED: 331 state = newState; 332 LockSupport.unpark(this); 333 break; 334 case SLEEPING: 335 state = newState; 336 this.interrupt(); 337 break; 338 default: 339 state = newState; 340 break; 341 } 342 iterations=0; 343 interrupted=0; 344 } 345 } 346 } |