publicclass Test924 { publicstaticvoid run() throws Exception { // Run the test on its own thread, so we have a known state for the "current" thread. Thread t = newThread("TestThread") {
@Override publicvoid run() { try {
doTest();
} catch (Exception e) { thrownew RuntimeException(e);
}
}
};
t.start();
t.join();
}
// Need to adjust priority, as on-device this may be unexpected (and we prefer not // to special-case this.)
t1.setPriority(5);
if (t1 != t2) { thrownew RuntimeException("Expected " + t1 + " but got " + t2);
}
System.out.println("currentThread OK");
printThreadInfo(t1);
printThreadInfo(null);
Thread t3 = newThread("Daemon Thread");
t3.setDaemon(true); // Do not start this thread, yet.
printThreadInfo(t3); // Start, and wait for it to die.
t3.start();
t3.join(); Thread.sleep(500); // Wait a little bit. // Thread has died, check that we can still get info.
printThreadInfo(t3);
// Try a subclass of thread. Thread t4 = newThread("Subclass") {
};
printThreadInfo(t4);
privatestaticvoid doStateTests(Function<Runnable, Thread> mkThread) throws Exception { final CountDownLatch cdl1 = new CountDownLatch(1); final CountDownLatch cdl2 = new CountDownLatch(1); final CountDownLatch cdl3_1 = new CountDownLatch(1); final CountDownLatch cdl3_2 = new CountDownLatch(1); final CountDownLatch cdl4 = new CountDownLatch(1); final CountDownLatch cdl5 = new CountDownLatch(1); final Holder h = new Holder(); finallong ALMOST_INFINITE = 100000000; // 1.1 days! final NativeWaiter w = new NativeWaiter();
Runnable r = new Runnable() {
@Override publicvoid run() { try {
cdl1.countDown(); synchronized(cdl1) {
cdl1.wait();
}
Thread t = mkThread.apply(r);
System.out.println("Thread type is " + t.getClass());
printThreadState(t);
t.start();
// Waiting.
cdl1.await(); // This is super inconsistent so just wait for the desired state for up to 5 minutes then give // up and continue finalint WAITING_INDEF = 0x191;
waitForState(t, WAITING_INDEF); synchronized(cdl1) {
cdl1.notifyAll();
}
// Timed waiting.
cdl2.await(); // This is super inconsistent so just wait for the desired state for up to 5 minutes then give // up and continue finalint WAITING_TIMED = 0x1a1;
waitForState(t, WAITING_TIMED); synchronized(cdl2) {
cdl2.notifyAll();
}
// Blocked on monitor. synchronized(cdl3_2) {
cdl3_1.countDown();
cdl3_2.await(); // While the latch improves the chances to make good progress, scheduling might still be // messy. Wait till we get the right Java-side Thread state. do { Thread.yield();
} while (t.getState() != Thread.State.BLOCKED); // Since internal thread suspension (For GC or other cases) can happen at any time and changes // the thread state we just have it print the majority thread state across 11 calls over 55 // milliseconds.
printMajorityThreadState(t, 11, 5);
}
// Sleeping.
cdl4.await(); // This is super inconsistent so just wait for the desired state for up to 5 minutes then give // up and continue finalint WAITING_SLEEP = 0xe1;
waitForState(t, WAITING_SLEEP);
t.interrupt();
privatestaticvoid waitForState(Thread t, int desired) throws Exception { Thread.yield(); Thread.sleep(1000); // This is super inconsistent so just wait for the desired state for up to 5 minutes then give // up and continue int state;
Instant deadline = Instant.now().plusSeconds(60 * 5); while ((state = getThreadState(t)) != desired && deadline.isAfter(Instant.now())) { Thread.yield(); Thread.sleep(100); Thread.yield();
}
printThreadState(state);
}
List<Thread> expectedList = new ArrayList<>();
Set<Thread> threadsFromTraces = Thread.getAllStackTraces().keySet();
expectedList.add(findThreadByName(threadsFromTraces, "FinalizerDaemon"));
expectedList.add(findThreadByName(threadsFromTraces, "FinalizerWatchdogDaemon"));
expectedList.add(findThreadByName(threadsFromTraces, "HeapTaskDaemon"));
expectedList.add(findThreadByName(threadsFromTraces, "ReferenceQueueDaemon")); // We can't get the signal catcher through getAllStackTraces. So ignore it. // expectedList.add(findThreadByName(threadsFromTraces, "Signal Catcher"));
expectedList.add(findThreadByName(threadsFromTraces, "TestThread"));
expectedList.add(findThreadByName(threadsFromTraces, "main"));
if (!threadList.containsAll(expectedList)) { thrownew RuntimeException("Expected " + expectedList + " as subset, got " + threadList);
}
System.out.println(expectedList);
}
privatestaticThread findThreadByName(Set<Thread> threads, String name) { for (Thread t : threads) { if (t.getName().equals(name)) { return t;
}
} thrownew RuntimeException("Did not find thread " + name + ": " + threads);
}
// Check that there are no events related to EventTestThread that we just created.
System.out.println(filterForThread(getThreadEventMessages(), thread_name).toString());
// Call getThreadState 'votes' times waiting 'wait' millis between calls and print the most common // result. privatestaticvoid printMajorityThreadState(Thread t, int votes, int wait) throws Exception {
Map<Integer, Integer> states = new HashMap<>(); for (int i = 0; i < votes; i++) { int cur_state = getThreadState(t);
states.put(cur_state, states.getOrDefault(cur_state, 0) + 1); Thread.sleep(wait); // Wait a little bit.
} int best_state = -1; int highest_count = 0; for (Map.Entry<Integer, Integer> e : states.entrySet()) { if (e.getValue() > highest_count) {
highest_count = e.getValue();
best_state = e.getKey();
}
}
printThreadState(best_state);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.