1 7 8 package java.lang; 9 10 import java.security.AccessController ; 11 import java.security.AccessControlContext ; 12 import java.security.PrivilegedAction ; 13 import java.util.Map ; 14 import java.util.HashMap ; 15 import java.util.Collections ; 16 import java.util.concurrent.locks.LockSupport ; 17 import sun.misc.SoftCache; 18 import sun.nio.ch.Interruptible; 19 import sun.security.util.SecurityConstants; 20 21 22 114 public 115 class Thread implements Runnable { 116 117 private static native void registerNatives(); 118 static { 119 registerNatives(); 120 } 121 122 private char name[]; 123 private int priority; 124 private Thread threadQ; 125 private long eetop; 126 private boolean started; 128 129 private boolean single_step; 130 131 132 private boolean daemon = false; 133 134 135 private boolean stillborn = false; 136 137 138 private Runnable target; 139 140 141 private ThreadGroup group; 142 143 144 private ClassLoader contextClassLoader; 145 146 147 private AccessControlContext inheritedAccessControlContext; 148 149 150 private static int threadInitNumber; 151 private static synchronized int nextThreadNum() { 152 return threadInitNumber++; 153 } 154 155 157 ThreadLocal.ThreadLocalMap threadLocals = null; 158 159 163 ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; 164 165 170 private long stackSize; 171 172 175 private long tid; 176 177 178 private static long threadSeqNumber; 179 180 183 private int threadStatus = 0; 184 185 186 private static synchronized long nextThreadID() { 187 return ++threadSeqNumber; 188 } 189 190 194 private volatile Interruptible blocker; 195 private Object blockerLock = new Object (); 196 197 199 void blockedOn(Interruptible b) { 200 synchronized (blockerLock) { 201 blocker = b; 202 } 203 } 204 205 208 public final static int MIN_PRIORITY = 1; 209 210 213 public final static int NORM_PRIORITY = 5; 214 215 218 public final static int MAX_PRIORITY = 10; 219 220 225 public static native Thread currentThread(); 226 227 231 public static native void yield(); 232 233 244 public static native void sleep(long millis) throws InterruptedException ; 245 246 261 public static void sleep(long millis, int nanos) 262 throws InterruptedException { 263 if (millis < 0) { 264 throw new IllegalArgumentException ("timeout value is negative"); 265 } 266 267 if (nanos < 0 || nanos > 999999) { 268 throw new IllegalArgumentException ( 269 "nanosecond timeout value out of range"); 270 } 271 272 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 273 millis++; 274 } 275 276 sleep(millis); 277 } 278 279 288 private void init(ThreadGroup g, Runnable target, String name, 289 long stackSize) { 290 Thread parent = currentThread(); 291 SecurityManager security = System.getSecurityManager(); 292 if (g == null) { 293 294 295 297 if (security != null) { 298 g = security.getThreadGroup(); 299 } 300 301 303 if (g == null) { 304 g = parent.getThreadGroup(); 305 } 306 } 307 308 310 g.checkAccess(); 311 312 315 if (security != null) { 316 if (isCCLOverridden(getClass())) { 317 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 318 } 319 } 320 321 322 g.addUnstarted(); 323 324 this.group = g; 325 this.daemon = parent.isDaemon(); 326 this.priority = parent.getPriority(); 327 this.name = name.toCharArray(); 328 if (security == null || isCCLOverridden(parent.getClass())) 329 this.contextClassLoader = parent.getContextClassLoader(); 330 else 331 this.contextClassLoader = parent.contextClassLoader; 332 this.inheritedAccessControlContext = AccessController.getContext(); 333 this.target = target; 334 setPriority(priority); 335 if (parent.inheritableThreadLocals != null) 336 this.inheritableThreadLocals = 337 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); 338 339 this.stackSize = stackSize; 340 341 342 tid = nextThreadID(); 343 } 344 345 355 public Thread() { 356 init(null, null, "Thread-" + nextThreadNum(), 0); 357 } 358 359 370 public Thread(Runnable target) { 371 init(null, target, "Thread-" + nextThreadNum(), 0); 372 } 373 374 388 public Thread(ThreadGroup group, Runnable target) { 389 init(group, target, "Thread-" + nextThreadNum(), 0); 390 } 391 392 400 public Thread(String name) { 401 init(null, null, name, 0); 402 } 403 404 415 public Thread(ThreadGroup group, String name) { 416 init(group, null, name, 0); 417 } 418 419 428 public Thread(Runnable target, String name) { 429 init(null, target, name, 0); 430 } 431 432 486 public Thread(ThreadGroup group, Runnable target, String name) { 487 init(group, target, name, 0); 488 } 489 490 546 public Thread(ThreadGroup group, Runnable target, String name, 547 long stackSize) { 548 init(group, target, name, stackSize); 549 } 550 551 569 public synchronized void start() { 570 if (started) 571 throw new IllegalThreadStateException (); 572 started = true; 573 group.add(this); 574 start0(); 575 } 576 577 private native void start0(); 578 579 593 public void run() { 594 if (target != null) { 595 target.run(); 596 } 597 } 598 599 603 private void exit() { 604 if (group != null) { 605 group.remove(this); 606 group = null; 607 } 608 609 target = null; 610 611 threadLocals = null; 612 inheritableThreadLocals = null; 613 inheritedAccessControlContext = null; 614 blocker = null; 615 uncaughtExceptionHandler = null; 616 } 617 618 685 @Deprecated 686 public final void stop() { 687 synchronized (this) { 688 if (!this.isAlive()) return; 690 SecurityManager security = System.getSecurityManager(); 691 if (security != null) { 692 checkAccess(); 693 if (this != Thread.currentThread()) { 694 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); 695 } 696 } 697 resume(); stop0(new ThreadDeath ()); 699 } 700 } 701 702 750 @Deprecated 751 public final synchronized void stop(Throwable obj) { 752 SecurityManager security = System.getSecurityManager(); 753 if (security != null) { 754 checkAccess(); 755 if ((this != Thread.currentThread()) || 756 (!(obj instanceof ThreadDeath ))) { 757 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); 758 } 759 } 760 resume(); stop0(obj); 762 } 763 764 801 public void interrupt() { 802 if (this != Thread.currentThread()) 803 checkAccess(); 804 805 synchronized (blockerLock) { 806 Interruptible b = blocker; 807 if (b != null) { 808 interrupt0(); b.interrupt(); 810 return; 811 } 812 } 813 interrupt0(); 814 } 815 816 828 public static boolean interrupted() { 829 return currentThread().isInterrupted(true); 830 } 831 832 840 public boolean isInterrupted() { 841 return isInterrupted(false); 842 } 843 844 849 private native boolean isInterrupted(boolean ClearInterrupted); 850 851 868 @Deprecated 869 public void destroy() { 870 throw new NoSuchMethodError (); 871 } 872 873 880 public final native boolean isAlive(); 881 882 906 @Deprecated 907 public final void suspend() { 908 checkAccess(); 909 suspend0(); 910 } 911 912 932 @Deprecated 933 public final void resume() { 934 checkAccess(); 935 resume0(); 936 } 937 938 963 public final void setPriority(int newPriority) { 964 checkAccess(); 965 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { 966 throw new IllegalArgumentException (); 967 } 968 if (newPriority > group.getMaxPriority()) { 969 newPriority = group.getMaxPriority(); 970 } 971 setPriority0(priority = newPriority); 972 } 973 974 981 public final int getPriority() { 982 return priority; 983 } 984 985 1000 public final void setName(String name) { 1001 checkAccess(); 1002 this.name = name.toCharArray(); 1003 } 1004 1005 1012 public final String getName() { 1013 return String.valueOf(name); 1014 } 1015 1016 1023 public final ThreadGroup getThreadGroup() { 1024 return group; 1025 } 1026 1027 1034 public static int activeCount() { 1035 return currentThread().getThreadGroup().activeCount(); 1036 } 1037 1038 1057 public static int enumerate(Thread tarray[]) { 1058 return currentThread().getThreadGroup().enumerate(tarray); 1059 } 1060 1061 1072 @Deprecated 1073 public native int countStackFrames(); 1074 1075 1084 public final synchronized void join(long millis) 1085 throws InterruptedException { 1086 long base = System.currentTimeMillis(); 1087 long now = 0; 1088 1089 if (millis < 0) { 1090 throw new IllegalArgumentException ("timeout value is negative"); 1091 } 1092 1093 if (millis == 0) { 1094 while (isAlive()) { 1095 wait(0); 1096 } 1097 } else { 1098 while (isAlive()) { 1099 long delay = millis - now; 1100 if (delay <= 0) { 1101 break; 1102 } 1103 wait(delay); 1104 now = System.currentTimeMillis() - base; 1105 } 1106 } 1107 } 1108 1109 1121 public final synchronized void join(long millis, int nanos) 1122 throws InterruptedException { 1123 1124 if (millis < 0) { 1125 throw new IllegalArgumentException ("timeout value is negative"); 1126 } 1127 1128 if (nanos < 0 || nanos > 999999) { 1129 throw new IllegalArgumentException ( 1130 "nanosecond timeout value out of range"); 1131 } 1132 1133 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 1134 millis++; 1135 } 1136 1137 join(millis); 1138 } 1139 1140 1147 public final void join() throws InterruptedException { 1148 join(0); 1149 } 1150 1151 1157 public static void dumpStack() { 1158 new Exception ("Stack trace").printStackTrace(); 1159 } 1160 1161 1181 public final void setDaemon(boolean on) { 1182 checkAccess(); 1183 if (isAlive()) { 1184 throw new IllegalThreadStateException (); 1185 } 1186 daemon = on; 1187 } 1188 1189 1196 public final boolean isDaemon() { 1197 return daemon; 1198 } 1199 1200 1215 public final void checkAccess() { 1216 SecurityManager security = System.getSecurityManager(); 1217 if (security != null) { 1218 security.checkAccess(this); 1219 } 1220 } 1221 1222 1228 public String toString() { 1229 ThreadGroup group = getThreadGroup(); 1230 if (group != null) { 1231 return "Thread[" + getName() + "," + getPriority() + "," + 1232 group.getName() + "]"; 1233 } else { 1234 return "Thread[" + getName() + "," + getPriority() + "," + 1235 "" + "]"; 1236 } 1237 } 1238 1239 1268 public ClassLoader getContextClassLoader() { 1269 if (contextClassLoader == null) 1270 return null; 1271 SecurityManager sm = System.getSecurityManager(); 1272 if (sm != null) { 1273 ClassLoader ccl = ClassLoader.getCallerClassLoader(); 1274 if (ccl != null && ccl != contextClassLoader && 1275 !contextClassLoader.isAncestor(ccl)) { 1276 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1277 } 1278 } 1279 return contextClassLoader; 1280 } 1281 1282 1303 public void setContextClassLoader(ClassLoader cl) { 1304 SecurityManager sm = System.getSecurityManager(); 1305 if (sm != null) { 1306 sm.checkPermission(new RuntimePermission ("setContextClassLoader")); 1307 } 1308 contextClassLoader = cl; 1309 } 1310 1311 1327 public static native boolean holdsLock(Object obj); 1328 1329 private static final StackTraceElement [] EMPTY_STACK_TRACE 1330 = new StackTraceElement [0]; 1331 1332 1367 public StackTraceElement [] getStackTrace() { 1368 if (this != Thread.currentThread()) { 1369 SecurityManager security = System.getSecurityManager(); 1371 if (security != null) { 1372 security.checkPermission( 1373 SecurityConstants.GET_STACK_TRACE_PERMISSION); 1374 } 1375 } 1376 1377 if (!isAlive()) { 1378 return EMPTY_STACK_TRACE; 1379 } 1380 1381 Thread [] threads = new Thread [1]; 1382 threads[0] = this; 1383 StackTraceElement [][] result = dumpThreads(threads); 1384 return result[0]; 1385 } 1386 1387 1422 public static Map <Thread , StackTraceElement []> getAllStackTraces() { 1423 SecurityManager security = System.getSecurityManager(); 1425 if (security != null) { 1426 security.checkPermission( 1427 SecurityConstants.GET_STACK_TRACE_PERMISSION); 1428 security.checkPermission( 1429 SecurityConstants.MODIFY_THREADGROUP_PERMISSION); 1430 } 1431 1432 Thread [] threads = getThreads(); 1434 StackTraceElement [][] traces = dumpThreads(threads); 1435 Map <Thread , StackTraceElement []> m 1436 = new HashMap <Thread , StackTraceElement []>(threads.length); 1437 for (int i = 0; i < threads.length; i++) { 1438 if (threads[i].isAlive()) { 1439 StackTraceElement [] stackTrace = traces[i]; 1440 if (stackTrace == null) { 1441 stackTrace = EMPTY_STACK_TRACE; 1442 } 1443 m.put(threads[i], stackTrace); 1444 } 1445 } 1446 return m; 1447 } 1448 1449 1450 private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = 1451 new RuntimePermission ("enableContextClassLoaderOverride"); 1452 1453 1454 private static final SoftCache subclassAudits = new SoftCache(10); 1455 1456 1457 1463 private static boolean isCCLOverridden(Class cl) { 1464 if (cl == Thread .class) 1465 return false; 1466 Boolean result = null; 1467 synchronized (subclassAudits) { 1468 result = (Boolean ) subclassAudits.get(cl); 1469 if (result == null) { 1470 1475 result = new Boolean (auditSubclass(cl)); 1476 subclassAudits.put(cl, result); 1477 } 1478 } 1479 return result.booleanValue(); 1480 } 1481 1482 1487 private static boolean auditSubclass(final Class subcl) { 1488 Boolean result = (Boolean ) AccessController.doPrivileged( 1489 new PrivilegedAction () { 1490 public Object run() { 1491 for (Class cl = subcl; 1492 cl != Thread .class; 1493 cl = cl.getSuperclass()) 1494 { 1495 try { 1496 cl.getDeclaredMethod("getContextClassLoader", new Class [0]); 1497 return Boolean.TRUE; 1498 } catch (NoSuchMethodException ex) { 1499 } 1500 try { 1501 Class [] params = {ClassLoader .class}; 1502 cl.getDeclaredMethod("setContextClassLoader", params); 1503 return Boolean.TRUE; 1504 } catch (NoSuchMethodException ex) { 1505 } 1506 } 1507 return Boolean.FALSE; 1508 } 1509 } 1510 ); 1511 return result.booleanValue(); 1512 } 1513 1514 private native static StackTraceElement [][] dumpThreads(Thread [] threads); 1515 private native static Thread [] getThreads(); 1516 1517 1526 public long getId() { 1527 return tid; 1528 } 1529 1530 1564 public enum State { 1565 1568 NEW, 1569 1570 1576 RUNNABLE, 1577 1578 1585 BLOCKED, 1586 1587 1606 WAITING, 1607 1608 1620 TIMED_WAITING, 1621 1622 1626 TERMINATED; 1627 } 1628 1629 1637 public State getState() { 1638 return sun.misc.VM.toThreadState(threadStatus); 1640 } 1641 1642 1644 1666 public interface UncaughtExceptionHandler { 1667 1675 void uncaughtException(Thread t, Throwable e); 1676 } 1677 1678 private volatile UncaughtExceptionHandler uncaughtExceptionHandler; 1680 1681 private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; 1683 1684 1718 public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 1719 SecurityManager sm = System.getSecurityManager(); 1720 if (sm != null) { 1721 sm.checkPermission( 1722 new RuntimePermission ("setDefaultUncaughtExceptionHandler") 1723 ); 1724 } 1725 1726 defaultUncaughtExceptionHandler = eh; 1727 } 1728 1729 1736 public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){ 1737 return defaultUncaughtExceptionHandler; 1738 } 1739 1740 1748 public UncaughtExceptionHandler getUncaughtExceptionHandler() { 1749 return uncaughtExceptionHandler != null ? 1750 uncaughtExceptionHandler : group; 1751 } 1752 1753 1768 public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 1769 checkAccess(); 1770 uncaughtExceptionHandler = eh; 1771 } 1772 1773 1777 private void dispatchUncaughtException(Throwable e) { 1778 getUncaughtExceptionHandler().uncaughtException(this, e); 1779 } 1780 1781 1782 private native void setPriority0(int newPriority); 1783 private native void stop0(Object o); 1784 private native void suspend0(); 1785 private native void resume0(); 1786 private native void interrupt0(); 1787} 1788 | Popular Tags |