DoneTimedGetLoops.java revision 12745:f068a4ffddd2
1/* 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 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 * Written by Martin Buchholz with assistance from members of JCP JSR-166 26 * Expert Group and released to the public domain, as explained at 27 * http://creativecommons.org/publicdomain/zero/1.0/ 28 */ 29 30/* 31 * @test 32 * @run main DoneTimedGetLoops 300 33 * @summary isDone returning true guarantees that subsequent timed get 34 * will never throw TimeoutException. 35 */ 36 37import java.util.*; 38import java.util.concurrent.*; 39import java.util.concurrent.atomic.*; 40 41@SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) 42public class DoneTimedGetLoops { 43 final long testDurationMillisDefault = 10L * 1000L; 44 final long testDurationMillis; 45 46 static class PublicFutureTask extends FutureTask<Boolean> { 47 static final Runnable noop = new Runnable() { public void run() {} }; 48 PublicFutureTask() { super(noop, null); } 49 public void set(Boolean v) { super.set(v); } 50 public void setException(Throwable t) { super.setException(t); } 51 } 52 53 DoneTimedGetLoops(String[] args) { 54 testDurationMillis = (args.length > 0) ? 55 Long.valueOf(args[0]) : testDurationMillisDefault; 56 } 57 58 void test(String[] args) throws Throwable { 59 final long testDurationNanos = testDurationMillis * 1000L * 1000L; 60 final long quittingTimeNanos = System.nanoTime() + testDurationNanos; 61 final long timeoutMillis = 10L * 1000L; 62 63 final AtomicReference<PublicFutureTask> normalRef 64 = new AtomicReference<PublicFutureTask>(); 65 final AtomicReference<PublicFutureTask> abnormalRef 66 = new AtomicReference<PublicFutureTask>(); 67 68 final Throwable throwable = new Throwable(); 69 70 abstract class CheckedThread extends Thread { 71 CheckedThread(String name) { 72 super(name); 73 setDaemon(true); 74 start(); 75 } 76 /** Polls for quitting time. */ 77 protected boolean quittingTime() { 78 return System.nanoTime() - quittingTimeNanos > 0; 79 } 80 /** Polls occasionally for quitting time. */ 81 protected boolean quittingTime(long i) { 82 return (i % 1024) == 0 && quittingTime(); 83 } 84 protected abstract void realRun() throws Exception; 85 public void run() { 86 try { realRun(); } catch (Throwable t) { unexpected(t); } 87 } 88 } 89 90 Thread setter = new CheckedThread("setter") { 91 protected void realRun() { 92 while (! quittingTime()) { 93 PublicFutureTask future = new PublicFutureTask(); 94 normalRef.set(future); 95 future.set(Boolean.TRUE); 96 }}}; 97 98 Thread setterException = new CheckedThread("setterException") { 99 protected void realRun() { 100 while (! quittingTime()) { 101 PublicFutureTask future = new PublicFutureTask(); 102 abnormalRef.set(future); 103 future.setException(throwable); 104 }}}; 105 106 Thread doneTimedGetNormal = new CheckedThread("doneTimedGetNormal") { 107 protected void realRun() throws Exception { 108 while (! quittingTime()) { 109 PublicFutureTask future = normalRef.get(); 110 if (future != null) { 111 while (!future.isDone()) 112 ; 113 check(future.get(0L, TimeUnit.HOURS) == Boolean.TRUE); 114 }}}}; 115 116 Thread doneTimedGetAbnormal = new CheckedThread("doneTimedGetAbnormal") { 117 protected void realRun() throws Exception { 118 while (! quittingTime()) { 119 PublicFutureTask future = abnormalRef.get(); 120 if (future != null) { 121 while (!future.isDone()) 122 ; 123 try { future.get(0L, TimeUnit.HOURS); fail(); } 124 catch (ExecutionException t) { 125 check(t.getCause() == throwable); 126 } 127 }}}}; 128 129 for (Thread thread : new Thread[] { 130 setter, 131 setterException, 132 doneTimedGetNormal, 133 doneTimedGetAbnormal }) { 134 thread.join(timeoutMillis + testDurationMillis); 135 if (thread.isAlive()) { 136 System.err.printf("Hung thread: %s%n", thread.getName()); 137 failed++; 138 for (StackTraceElement e : thread.getStackTrace()) 139 System.err.println(e); 140 // Kludge alert 141 thread.stop(); 142 thread.join(timeoutMillis); 143 } 144 } 145 } 146 147 //--------------------- Infrastructure --------------------------- 148 volatile int passed = 0, failed = 0; 149 void pass() {passed++;} 150 void fail() {failed++; Thread.dumpStack();} 151 void fail(String msg) {System.err.println(msg); fail();} 152 void unexpected(Throwable t) {failed++; t.printStackTrace();} 153 void check(boolean cond) {if (cond) pass(); else fail();} 154 void equal(Object x, Object y) { 155 if (x == null ? y == null : x.equals(y)) pass(); 156 else fail(x + " not equal to " + y);} 157 public static void main(String[] args) throws Throwable { 158 new DoneTimedGetLoops(args).instanceMain(args);} 159 public void instanceMain(String[] args) throws Throwable { 160 try {test(args);} catch (Throwable t) {unexpected(t);} 161 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 162 if (failed > 0) throw new AssertionError("Some tests failed");} 163} 164