1 /*
2 * Copyright (c) 1994, 2013, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package java.lang;
28 import java.lang.ref.Reference;
29 import java.lang.ref.ReferenceQueue;
30 import java.lang.ref.WeakReference;
31 import java.security.AccessController;
32 import java.security.AccessControlContext;
33 import java.security.PrivilegedAction;
34 import java.util.Map;
35 import java.util.HashMap;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.concurrent.ConcurrentMap;
38 import java.util.concurrent.locks.LockSupport;
39 import sun.nio.ch.Interruptible;
40 import sun.reflect.CallerSensitive;
41 import sun.reflect.Reflection;
42 import sun.security.util.SecurityConstants;
140 public
141 class Thread implements Runnable {
142 /* Make sure registerNatives is the first thing <clinit> does. */
143 private static native void registerNatives();
144 static {
145 registerNatives();
146 }
148 private volatile char name[];
149 private int priority;
150 private Thread threadQ;
151 private long eetop;
153 /* Whether or not to single_step this thread. */
154 private boolean single_step;
156 /* Whether or not the thread is a daemon thread. */
157 private boolean daemon = false;
159 /* JVM state */
160 private boolean stillborn = false;
162 /* What will be run. */
163 private Runnable target;
165 /* The group of this thread */
166 private ThreadGroup group;
168 /* The context ClassLoader for this thread */
169 private ClassLoader contextClassLoader;
171 /* The inherited AccessControlContext of this thread */
172 private AccessControlContext inheritedAccessControlContext;
174 /* For autonumbering anonymous threads. */
175 private static int threadInitNumber;
176 private static synchronized int nextThreadNum() {
177 return threadInitNumber++;
178 }
180 /* ThreadLocal values pertaining to this thread. This map is maintained
181 * by the ThreadLocal class. */
182 ThreadLocal.ThreadLocalMap threadLocals = null;
184 /*
185 * InheritableThreadLocal values pertaining to this thread. This map is
186 * maintained by the InheritableThreadLocal class.
187 */
188 ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
190 /*
191 * The requested stack size for this thread, or 0 if the creator did
192 * not specify a stack size. It is up to the VM to do whatever it
193 * likes with this number; some VMs will ignore it.
194 */
195 private long stackSize;
197 /*
198 * JVM-private state that persists after native thread termination.
199 */
200 private long nativeParkEventPointer;
202 /*
203 * Thread ID
204 */
205 private long tid;
207 /* For generating thread ID */
208 private static long threadSeqNumber;
210 /* Java thread status for tools,
211 * initialized to indicate thread 'not yet started'
212 */
214 private volatile int threadStatus = 0;
217 private static synchronized long nextThreadID() {
218 return ++threadSeqNumber;
219 }
227 volatile Object parkBlocker;
229 /* The object in which this thread is blocked in an interruptible I/O
230 * operation, if any. The blocker's interrupt method should be invoked
231 * after setting this thread's interrupt status.
232 */
233 private volatile Interruptible blocker;
234 private final Object blockerLock = new Object();
236 /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
237 */
238 void blockedOn(Interruptible b) {
239 synchronized (blockerLock) {
240 blocker = b;
241 }
242 }
247 public final static int MIN_PRIORITY = 1;
252 public final static int NORM_PRIORITY = 5;
257 public final static int MAX_PRIORITY = 10;
264 public static native Thread currentThread();
282 public static native void yield();
301 public static native void sleep(long millis) throws InterruptedException;
325 public static void sleep(long millis, int nanos)
326 throws InterruptedException {
327 if (millis < 0) {
328 throw new IllegalArgumentException("timeout value is negative");
329 }
331 if (nanos < 0 || nanos > 999999) {
332 throw new IllegalArgumentException(
333 "nanosecond timeout value out of range");
334 }
336 if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
337 millis++;
338 }
340 sleep(millis);
341 }
347 private void init(ThreadGroup g, Runnable target, String name,
348 long stackSize) {
349 init(g, target, name, stackSize, null);
350 }
363 private void init(ThreadGroup g, Runnable target, String name,
364 long stackSize, AccessControlContext acc) {
365 if (name == null) {
366 throw new NullPointerException("name cannot be null");
367 }
369 Thread parent = currentThread();
370 SecurityManager security = System.getSecurityManager();
371 if (g == null) {
372 /* Determine if it's an applet or not */
374 /* If there is a security manager, ask the security manager
375 what to do. */
376 if (security != null) {
377 g = security.getThreadGroup();
378 }
380 /* If the security doesn't have a strong opinion of the matter
381 use the parent thread group. */
382 if (g == null) {
383 g = parent.getThreadGroup();
384 }
385 }
387 /* checkAccess regardless of whether or not threadgroup is
388 explicitly passed in. */
389 g.checkAccess();
391 /*
392 * Do we have the required permissions?
393 */
394 if (security != null) {
395 if (isCCLOverridden(getClass())) {
396 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
397 }
398 }
400 g.addUnstarted();
402 this.group = g;
403 this.daemon = parent.isDaemon();
404 this.priority = parent.getPriority();
405 this.name = name.toCharArray();
406 if (security == null || isCCLOverridden(parent.getClass()))
407 this.contextClassLoader = parent.getContextClassLoader();
408 else
409 this.contextClassLoader = parent.contextClassLoader;
410 this.inheritedAccessControlContext =
411 acc != null ? acc : AccessController.getContext();
412 this.target = target;
413 setPriority(priority);
414 if (parent.inheritableThreadLocals != null)
415 this.inheritableThreadLocals =
416 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
417 /* Stash the specified stack size in case the VM cares */
418 this.stackSize = stackSize;
420 /* Set thread ID */
421 tid = nextThreadID();
422 }
431 @Override
432 protected Object clone() throws CloneNotSupportedException {
433 throw new CloneNotSupportedException();
434 }
443 public Thread() {
444 init(null, null, "Thread-" + nextThreadNum(), 0);
445 }
459 public Thread(Runnable target) {
460 init(null, target, "Thread-" + nextThreadNum(), 0);
461 }
467 Thread(Runnable target, AccessControlContext acc) {
468 init(null, target, "Thread-" + nextThreadNum(), 0, acc);
469 }
494 public Thread(ThreadGroup group, Runnable target) {
495 init(group, target, "Thread-" + nextThreadNum(), 0);
496 }
506 public Thread(String name) {
507 init(null, null, name, 0);
508 }
530 public Thread(ThreadGroup group, String name) {
531 init(group, null, name, 0);
532 }
546 public Thread(Runnable target, String name) {
547 init(null, target, name, 0);
548 }
594 public Thread(ThreadGroup group, Runnable target, String name) {
595 init(group, target, name, 0);
596 }
672 public Thread(ThreadGroup group, Runnable target, String name,
673 long stackSize) {
674 init(group, target, name, stackSize);
675 }
695 public synchronized void start() {
703 if (threadStatus != 0)
704 throw new IllegalThreadStateException();
706 /* Notify the group that this thread is about to be started
707 * so that it can be added to the group's list of threads
708 * and the group's unstarted count can be decremented. */
709 group.add(this);
711 boolean started = false;
712 try {
713 start0();
714 started = true;
715 } finally {
716 try {
717 if (!started) {
718 group.threadStartFailed(this);
719 }
720 } catch (Throwable ignore) {
721 /* do nothing. If start0 threw a Throwable then
722 it will be passed up the call stack */
723 }
724 }
725 }
727 private native void start0();
741 @Override
742 public void run() {
743 if (target != null) {
744 target.run();
745 }
746 }
752 private void exit() {
753 if (group != null) {
754 group.threadTerminated(this);
755 group = null;
756 }
757 /* Aggressively null out all reference fields: see bug 4006245 */
758 target = null;
759 /* Speed the release of some of these resources */
760 threadLocals = null;
761 inheritableThreadLocals = null;
762 inheritedAccessControlContext = null;
763 blocker = null;
764 uncaughtExceptionHandler = null;
765 }
833 @Deprecated
834 public final void stop() {
835 SecurityManager security = System.getSecurityManager();
836 if (security != null) {
837 checkAccess();
838 if (this != Thread.currentThread()) {
839 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
840 }
841 }
842 // A zero status value corresponds to "NEW", it can't change to
843 // not-NEW because we hold the lock.
844 if (threadStatus != 0) {
845 resume(); // Wake up thread if it was suspended; no-op otherwise
846 }
848 // The VM can handle all thread states
849 stop0(new ThreadDeath());
850 }
866 @Deprecated
867 public final synchronized void stop(Throwable obj) {
868 throw new UnsupportedOperationException();
869 }
910 public void interrupt() {
911 if (this != Thread.currentThread())
912 checkAccess();
914 synchronized (blockerLock) {
915 Interruptible b = blocker;
916 if (b != null) {
917 interrupt0(); // Just to set the interrupt flag
918 b.interrupt(this);
919 return;
920 }
921 }
922 interrupt0();
923 }
942 public static boolean interrupted() {
943 return currentThread().isInterrupted(true);
944 }
959 public boolean isInterrupted() {
960 return isInterrupted(false);
961 }
968 private native boolean isInterrupted(boolean ClearInterrupted);
987 @Deprecated
988 public void destroy() {
989 throw new NoSuchMethodError();
990 }
999 public final native boolean isAlive();
1025 @Deprecated
1026 public final void suspend() {
1027 checkAccess();
1028 suspend0();
1029 }
1051 @Deprecated
1052 public final void resume() {
1053 checkAccess();
1054 resume0();
1055 }
1081 public final void setPriority(int newPriority) {
1082 ThreadGroup g;
1083 checkAccess();
1084 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
1085 throw new IllegalArgumentException();
1086 }
1087 if((g = getThreadGroup()) != null) {
1088 if (newPriority > g.getMaxPriority()) {
1089 newPriority = g.getMaxPriority();
1090 }
1091 setPriority0(priority = newPriority);
1092 }
1093 }
1101 public final int getPriority() {
1102 return priority;
1103 }
1119 public final synchronized void setName(String name) {
1120 checkAccess();
1121 this.name = name.toCharArray();
1122 if (threadStatus != 0) {
1123 setNativeName(name);
1124 }
1125 }
1133 public final String getName() {
1134 return new String(name, true);
1135 }
1144 public final ThreadGroup getThreadGroup() {
1145 return group;
1146 }
1164 public static int activeCount() {
1165 return currentThread().getThreadGroup().activeCount();
1166 }
1194 public static int enumerate(Thread tarray[]) {
1195 return currentThread().getThreadGroup().enumerate(tarray);
1196 }
1209 @Deprecated
1210 public native int countStackFrames();
1233 public final synchronized void join(long millis)
1234 throws InterruptedException {
1235 long base = System.currentTimeMillis();
1236 long now = 0;
1238 if (millis < 0) {
1239 throw new IllegalArgumentException("timeout value is negative");
1240 }
1242 if (millis == 0) {
1243 while (isAlive()) {
1244 wait(0);
1245 }
1246 } else {
1247 while (isAlive()) {
1248 long delay = millis - now;
1249 if (delay <= 0) {
1250 break;
1251 }
1252 wait(delay);
1253 now = System.currentTimeMillis() - base;
1254 }
1255 }
1256 }
1283 public final synchronized void join(long millis, int nanos)
1284 throws InterruptedException {
1286 if (millis < 0) {
1287 throw new IllegalArgumentException("timeout value is negative");
1288 }
1290 if (nanos < 0 || nanos > 999999) {
1291 throw new IllegalArgumentException(
1292 "nanosecond timeout value out of range");
1293 }
1295 if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
1296 millis++;
1297 }
1299 join(millis);
1300 }
1317 public final void join() throws InterruptedException {
1318 join(0);
1319 }
1327 public static void dumpStack() {
1328 new Exception("Stack trace").printStackTrace();
1329 }
1348 public final void setDaemon(boolean on) {
1349 checkAccess();
1350 if (isAlive()) {
1351 throw new IllegalThreadStateException();
1352 }
1353 daemon = on;
1354 }
1363 public final boolean isDaemon() {
1364 return daemon;
1365 }
1379 public final void checkAccess() {
1380 SecurityManager security = System.getSecurityManager();
1381 if (security != null) {
1382 security.checkAccess(this);
1383 }
1384 }
1392 public String toString() {
1393 ThreadGroup group = getThreadGroup();
1394 if (group != null) {
1395 return "Thread[" + getName() + "," + getPriority() + "," +
1396 group.getName() + "]";
1397 } else {
1398 return "Thread[" + getName() + "," + getPriority() + "," +
1399 "" + "]";
1400 }
1401 }
1429 @CallerSensitive
1430 public ClassLoader getContextClassLoader() {
1431 if (contextClassLoader == null)
1432 return null;
1433 SecurityManager sm = System.getSecurityManager();
1434 if (sm != null) {
1435 ClassLoader.checkClassLoaderPermission(contextClassLoader,
1436 Reflection.getCallerClass());
1437 }
1438 return contextClassLoader;
1439 }
1463 public void setContextClassLoader(ClassLoader cl) {
1464 SecurityManager sm = System.getSecurityManager();
1465 if (sm != null) {
1466 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
1467 }
1468 contextClassLoader = cl;
1469 }
1487 public static native boolean holdsLock(Object obj);
1489 private static final StackTraceElement[] EMPTY_STACK_TRACE
1490 = new StackTraceElement[0];
1528 public StackTraceElement[] getStackTrace() {
1529 if (this != Thread.currentThread()) {
1530 // check for getStackTrace permission
1531 SecurityManager security = System.getSecurityManager();
1532 if (security != null) {
1533 security.checkPermission(
1534 SecurityConstants.GET_STACK_TRACE_PERMISSION);
1535 }
1536 // optimization so we do not call into the vm for threads that
1537 // have not yet started or have terminated
1538 if (!isAlive()) {
1539 return EMPTY_STACK_TRACE;
1540 }
1541 StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
1542 StackTraceElement[] stackTrace = stackTraceArray[0];
1543 // a thread that was alive during the previous isAlive call may have
1544 // since terminated, therefore not having a stacktrace.
1545 if (stackTrace == null) {
1546 stackTrace = EMPTY_STACK_TRACE;
1547 }
1548 return stackTrace;
1549 } else {
1550 // Don't need JVM help for current thread
1551 return (new Exception()).getStackTrace();
1552 }
1553 }
1590 public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
1591 // check for getStackTrace permission
1592 SecurityManager security = System.getSecurityManager();
1593 if (security != null) {
1594 security.checkPermission(
1595 SecurityConstants.GET_STACK_TRACE_PERMISSION);
1596 security.checkPermission(
1597 SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
1598 }
1600 // Get a snapshot of the list of all threads
1601 Thread[] threads = getThreads();
1602 StackTraceElement[][] traces = dumpThreads(threads);
1603 Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
1604 for (int i = 0; i < threads.length; i++) {
1605 StackTraceElement[] stackTrace = traces[i];
1606 if (stackTrace != null) {
1607 m.put(threads[i], stackTrace);
1608 }
1609 // else terminated so we don't put it in the map
1610 }
1611 return m;
1612 }
1615 private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
1616 new RuntimePermission("enableContextClassLoaderOverride");
1619 /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
1620 * release */
1621 private static class Caches {
1623 static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
1624 new ConcurrentHashMap<>();
1627 static final ReferenceQueue<Class<?>> subclassAuditsQueue =
1628 new ReferenceQueue<>();
1629 }
1637 private static boolean isCCLOverridden(Class<?> cl) {
1638 if (cl == Thread.class)
1639 return false;
1641 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1642 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1643 Boolean result = Caches.subclassAudits.get(key);
1644 if (result == null) {
1645 result = Boolean.valueOf(auditSubclass(cl));
1646 Caches.subclassAudits.putIfAbsent(key, result);
1647 }
1649 return result.booleanValue();
1650 }
1657 private static boolean auditSubclass(final Class<?> subcl) {
1658 Boolean result = AccessController.doPrivileged(
1659 new PrivilegedAction<Boolean>() {
1660 public Boolean run() {
1661 for (Class<?> cl = subcl;
1662 cl != Thread.class;
1663 cl = cl.getSuperclass())
1664 {
1665 try {
1666 cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
1667 return Boolean.TRUE;
1668 } catch (NoSuchMethodException ex) {
1669 }
1670 try {
1671 Class<?>[] params = {ClassLoader.class};
1672 cl.getDeclaredMethod("setContextClassLoader", params);
1673 return Boolean.TRUE;
1674 } catch (NoSuchMethodException ex) {
1675 }
1676 }
1677 return Boolean.FALSE;
1678 }
1679 }
1680 );
1681 return result.booleanValue();
1682 }
1684 private native static StackTraceElement[][] dumpThreads(Thread[] threads);
1685 private native static Thread[] getThreads();
1696 public long getId() {
1697 return tid;
1698 }
1734 public enum State {
1738 NEW,
1746 RUNNABLE,
1755 BLOCKED,
1776 WAITING,
1790 TIMED_WAITING,
1796 TERMINATED;
1797 }
1807 public State getState() {
1808 // get current thread state
1809 return sun.misc.VM.toThreadState(threadStatus);
1810 }
1812 // Added in JSR-166
1813
1836 @FunctionalInterface
1837 public interface UncaughtExceptionHandler {
1846 void uncaughtException(Thread t, Throwable e);
1847 }
1849 // null unless explicitly set
1850 private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
1852 // null unless explicitly set
1853 private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
1889 public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
1890 SecurityManager sm = System.getSecurityManager();
1891 if (sm != null) {
1892 sm.checkPermission(
1893 new RuntimePermission("setDefaultUncaughtExceptionHandler")
1894 );
1895 }
1897 defaultUncaughtExceptionHandler = eh;
1898 }
1908 public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
1909 return defaultUncaughtExceptionHandler;
1910 }
1921 public UncaughtExceptionHandler getUncaughtExceptionHandler() {
1922 return uncaughtExceptionHandler != null ?
1923 uncaughtExceptionHandler : group;
1924 }
1941 public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
1942 checkAccess();
1943 uncaughtExceptionHandler = eh;
1944 }
1950 private void dispatchUncaughtException(Throwable e) {
1951 getUncaughtExceptionHandler().uncaughtException(this, e);
1952 }
1958 static void processQueue(ReferenceQueue<Class<?>> queue,
1959 ConcurrentMap<? extends
1960 WeakReference<Class<?>>, ?> map)
1961 {
1962 Reference<? extends Class<?>> ref;
1963 while((ref = queue.poll()) != null) {
1964 map.remove(ref);
1965 }
1966 }
1971 static class WeakClassKey extends WeakReference<Class<?>> {
1976 private final int hash;
1982 WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
1983 super(cl, refQueue);
1984 hash = System.identityHashCode(cl);
1985 }
1990 @Override
1991 public int hashCode() {
1992 return hash;
1993 }
2001 @Override
2002 public boolean equals(Object obj) {
2003 if (obj == this)
2004 return true;
2006 if (obj instanceof WeakClassKey) {
2007 Object referent = get();
2008 return (referent != null) &&
2009 (referent == ((WeakClassKey) obj).get());
2010 } else {
2011 return false;
2012 }
2013 }
2014 }
2017 // The following three initially uninitialized fields are exclusively
2018 // managed by class java.util.concurrent.ThreadLocalRandom. These
2019 // fields are used to build the high-performance PRNGs in the
2020 // concurrent code, and we can not risk accidental false sharing.
2021 // Hence, the fields are isolated with @Contended.
2022
2024 @sun.misc.Contended("tlr")
2025 long threadLocalRandomSeed;
2028 @sun.misc.Contended("tlr")
2029 int threadLocalRandomProbe;
2032 @sun.misc.Contended("tlr")
2033 int threadLocalRandomSecondarySeed;
2035 /* Some private helper methods */
2036 private native void setPriority0(int newPriority);
2037 private native void stop0(Object o);
2038 private native void suspend0();
2039 private native void resume0();
2040 private native void interrupt0();
2041 private native void setNativeName(String name);
2042 }