死磕JDK源码之Thread
1 package java.lang; 2 3 import java.lang.ref.Reference; 4 import java.lang.ref.ReferenceQueue; 5 import java.lang.ref.WeakReference; 6 import java.security.AccessController; 7 import java.security.AccessControlContext; 8 import java.security.PrivilegedAction; 9 import java.util.Map; 10 import java.util.HashMap; 11 import java.util.concurrent.ConcurrentHashMap; 12 import java.util.concurrent.ConcurrentMap; 13 import java.util.concurrent.locks.LockSupport; 14 15 import sun.nio.ch.Interruptible; 16 import sun.reflect.CallerSensitive; 17 import sun.reflect.Reflection; 18 import sun.security.util.SecurityConstants; 19 20 /* 21 Every thread has a priority. Threads with higher priority are executed in preference to threads 22 with lower priority. 23 Each thread may or may not also be marked as a daemon. When code running in some thread creates a 24 new <code>Thread</code> object,the new thread has its priority initially set equal to the priority 25 of the creating thread, and is a daemon thread if and only if the creating thread is a daemon. 26 27 When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically 28 calls the method named <code>main</code> of some designated class). The Java Virtual Machine continues 29 to execute threads until either of the following occurs: 30 1.The <code>exit</code> method of class <code>Runtime</code> has been called and the security manager 31 has permitted the exit operation to take place. 32 2.All threads that are not daemon threads have died, either by returning from the call to the 33 <code>run</code> method or by throwing an exception that propagates beyond the <code>run</code> method. 34 35 Every thread has a name for identification purposes. More than one thread may have the same name. If a name 36 is not specified when a thread is created, a new name is generated for it.Unless otherwise noted, passing a 37 {@code null} argument to a constructor or method in this class will cause a {@link NullPointerException} to be thrown. 38 */ 39 public class Thread implements Runnable { 40 private static native void registerNatives(); 41 42 static { 43 registerNatives(); 44 } 45 46 private volatile char name[]; 47 private int priority; 48 private Thread threadQ; 49 private long eetop; 50 51 //是否单步执行线程 52 private boolean single_step; 53 54 //是否为守护线程 55 private boolean daemon = false; 56 57 //JVM状态 58 private boolean stillborn = false; 59 60 //run方法执行的目标代码 61 private Runnable target; 62 63 //线程所属的线程组 64 private ThreadGroup group; 65 66 //线程的类加载器 67 private ClassLoader contextClassLoader; 68 69 //线程继承的AccessControlContext 70 private AccessControlContext inheritedAccessControlContext; 71 72 //默认生成的线程名"Thread-" + nextThreadNum() 73 private static int threadInitNumber; 74 75 private static synchronized int nextThreadNum() { 76 return threadInitNumber++; 77 } 78 79 ThreadLocal.ThreadLocalMap threadLocals = null; 80 81 ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; 82 83 //线程请求栈的深度,如果线程创建者未指定栈深度则其值为0,stackSize如何用完全取决于虚拟机,有的虚拟机会忽略stackSize 84 private long stackSize; 85 86 //本地线程终止后,JVM私有的值 87 private long nativeParkEventPointer; 88 89 //线程id 90 private long tid; 91 92 //用于生成线程ID 93 private static long threadSeqNumber; 94 95 //为工具提供的线程状态值,0表示当前线程还未运行 96 private volatile int threadStatus = 0; 97 98 //获取下一个线程tid 99 private static synchronized long nextThreadID() { 100 return ++threadSeqNumber; 101 } 102 103 /* 104 parkBlocker用于调用java.util.concurrent.locks.LockSupport.park方法 105 通过java.util.concurrent.locks.LockSupport.setBlocker方法set 106 通过java.util.concurrent.locks.LockSupport.getBlocker方法get 107 */ 108 volatile Object parkBlocker; 109 110 /* 111 The object in which this thread is blocked in an interruptible I/O operation, if any. 112 The blocker's interrupt method should be invoked after setting this thread's interrupt status. 113 */ 114 private volatile Interruptible blocker; 115 private final Object blockerLock = new Object(); 116 117 void blockedOn(Interruptible b) { 118 synchronized (blockerLock) { 119 blocker = b; 120 } 121 } 122 123 //线程的最低优先级 124 public final static int MIN_PRIORITY = 1; 125 126 //线程的默认优先级 127 public final static int NORM_PRIORITY = 5; 128 129 //线程的最高优先级 130 public final static int MAX_PRIORITY = 10; 131 132 //返回当前正在执行线程对象的引用 133 public static native Thread currentThread(); 134 135 /* 136 A hint to the scheduler that the current thread is willing to yield 137 its current use of a processor. The scheduler is free to ignore this hint. 138 */ 139 public static native void yield(); 140 141 //调用sleep方法会使得当前线程临时停止执行指定毫秒数,sleep不释放锁 142 public static native void sleep(long millis) throws InterruptedException; 143 144 public static void sleep(long millis, int nanos) 145 throws InterruptedException { 146 if (millis < 0) { 147 throw new IllegalArgumentException("timeout value is negative"); 148 } 149 150 if (nanos < 0 || nanos > 999999) { 151 throw new IllegalArgumentException( 152 "nanosecond timeout value out of range"); 153 } 154 155 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 156 millis++; 157 } 158 159 sleep(millis); 160 } 161 162 private void init(ThreadGroup g, Runnable target, String name, 163 long stackSize) { 164 init(g, target, name, stackSize, null); 165 } 166 167 private void init(ThreadGroup g, Runnable target, String name, 168 long stackSize, AccessControlContext acc) { 169 if (name == null) { 170 throw new NullPointerException("name cannot be null"); 171 } 172 173 this.name = name.toCharArray(); 174 175 Thread parent = currentThread(); 176 SecurityManager security = System.getSecurityManager(); 177 if (g == null) { 178 if (security != null) { 179 g = security.getThreadGroup(); 180 } 181 182 if (g == null) { 183 g = parent.getThreadGroup(); 184 } 185 } 186 187 g.checkAccess(); 188 189 if (security != null) { 190 if (isCCLOverridden(getClass())) { 191 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 192 } 193 } 194 195 g.addUnstarted(); 196 197 this.group = g; 198 this.daemon = parent.isDaemon(); 199 this.priority = parent.getPriority(); 200 if (security == null || isCCLOverridden(parent.getClass())) 201 this.contextClassLoader = parent.getContextClassLoader(); 202 else 203 this.contextClassLoader = parent.contextClassLoader; 204 this.inheritedAccessControlContext = 205 acc != null ? acc : AccessController.getContext(); 206 this.target = target; 207 setPriority(priority); 208 if (parent.inheritableThreadLocals != null) 209 this.inheritableThreadLocals = 210 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); 211 this.stackSize = stackSize; 212 213 tid = nextThreadID(); 214 } 215 216 //线程不支持Object的浅拷贝,取而代之的是构造一个新的线程 217 @Override 218 protected Object clone() throws CloneNotSupportedException { 219 throw new CloneNotSupportedException(); 220 } 221 222 public Thread() { 223 init(null, null, "Thread-" + nextThreadNum(), 0); 224 } 225 226 public Thread(Runnable target) { 227 init(null, target, "Thread-" + nextThreadNum(), 0); 228 } 229 230 Thread(Runnable target, AccessControlContext acc) { 231 init(null, target, "Thread-" + nextThreadNum(), 0, acc); 232 } 233 234 public Thread(ThreadGroup group, Runnable target) { 235 init(group, target, "Thread-" + nextThreadNum(), 0); 236 } 237 238 public Thread(String name) { 239 init(null, null, name, 0); 240 } 241 242 public Thread(ThreadGroup group, String name) { 243 init(group, null, name, 0); 244 } 245 246 public Thread(Runnable target, String name) { 247 init(null, target, name, 0); 248 } 249 250 public Thread(ThreadGroup group, Runnable target, String name) { 251 init(group, target, name, 0); 252 } 253 254 public Thread(ThreadGroup group, Runnable target, String name, 255 long stackSize) { 256 init(group, target, name, stackSize); 257 } 258 259 /* 260 Causes this thread to begin execution; the Java Virtual Machine calls 261 the <code>run</code> method of this thread. 262 The result is that two threads are running concurrently: the current thread 263 (which returns from the call to the <code>start</code> method) and the other 264 thread (which executes its <code>run</code> method). 265 266 public class ThreadTest { 267 public static void main(String[] args) throws InterruptedException { 268 Thread t1=new Thread(new Runnable() { 269 @Override 270 public void run() { 271 System.out.println("sakura"); 272 } 273 }); 274 t1.start(); 275 t1.join(); 276 t1.start(); 277 } 278 } 279 280 sakura 281 Exception in thread "main" java.lang.IllegalThreadStateException 282 at java.lang.Thread.start(Thread.java:705) 283 at ThreadTest.main(ThreadTest.java:11) 284 */ 285 public synchronized void start() { 286 //threadStatus=0表示线程处于NEW状态 287 if (threadStatus != 0) 288 throw new IllegalThreadStateException(); 289 290 group.add(this); 291 292 boolean started = false; 293 try { 294 start0(); 295 started = true; 296 } finally { 297 try { 298 if (!started) { 299 group.threadStartFailed(this); 300 } 301 } catch (Throwable ignore) { 302 303 } 304 } 305 } 306 307 private native void start0(); 308 309 @Override 310 public void run() { 311 if (target != null) { 312 target.run(); 313 } 314 } 315 316 //This method is called by the system to give a Thread a chance to clean up before it actually exits. 317 private void exit() { 318 if (group != null) { 319 group.threadTerminated(this); 320 group = null; 321 } 322 target = null; 323 threadLocals = null; 324 inheritableThreadLocals = null; 325 inheritedAccessControlContext = null; 326 blocker = null; 327 uncaughtExceptionHandler = null; 328 } 329 330 @Deprecated 331 public final void stop() { 332 SecurityManager security = System.getSecurityManager(); 333 if (security != null) { 334 checkAccess(); 335 if (this != Thread.currentThread()) { 336 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); 337 } 338 } 339 if (threadStatus != 0) { 340 resume(); 341 } 342 343 stop0(new ThreadDeath()); 344 } 345 346 @Deprecated 347 public final synchronized void stop(Throwable obj) { 348 throw new UnsupportedOperationException(); 349 } 350 351 /* 352 中断当前线程,如果不是当前线程中断自己,会调用checkAccess方法,这可能会抛出SecurityException 353 1.如果当前线程由于调用wait、join或sleep方法而阻塞,则中断状态会被清除且会抛出InterruptedException 354 2.如果线程由于java.nio.channels.InterruptibleChannel类中的InterruptibleChannel的I/O操作而被阻塞, 355 调用interrupt方法会使通道关闭且线程的中断状态会被重置并抛出ClosedByInterruptException 356 3.如果当前线程由于java.nio.channels.Selector而被阻塞,则线程的中断状态会被重置,且会立即从selection操作 357 返回一个非零值,这就和java.nio.channels.Selector的wakeup()方法被调用一样 358 如果以上条件都不成立,那么线程的中断状态被重置,中断一个非活跃线程不产生影响 359 */ 360 public void interrupt() { 361 if (this != Thread.currentThread()) 362 checkAccess(); 363 364 synchronized (blockerLock) { 365 Interruptible b = blocker; 366 if (b != null) { 367 interrupt0(); 368 b.interrupt(this); 369 return; 370 } 371 } 372 interrupt0(); 373 } 374 375 /* 376 测试当前线程是否被中断,并且清除中断状态 377 In other words, if this method were to be called twice in succession, the second 378 call would return false (unless the current thread were interrupted again, after 379 the first call had cleared its interrupted status and before the second call had examined it). 380 381 A thread interruption ignored because a thread was not alive at the time of the interrupt will 382 be reflected by this method returning false. 383 */ 384 public static boolean interrupted() { 385 return currentThread().isInterrupted(true); 386 } 387 388 //测试当前线程是否被中断,但不清除中断状态 389 public boolean isInterrupted() { 390 return isInterrupted(false); 391 } 392 393 private native boolean isInterrupted(boolean ClearInterrupted); 394 395 @Deprecated 396 public void destroy() { 397 throw new NoSuchMethodError(); 398 } 399 400 /* 401 判断线程是否处于存活状态 402 A thread is alive if it has been started and has not yet died. 403 */ 404 public final native boolean isAlive(); 405 406 @Deprecated 407 public final void suspend() { 408 checkAccess(); 409 suspend0(); 410 } 411 412 @Deprecated 413 public final void resume() { 414 checkAccess(); 415 resume0(); 416 } 417 418 //设置线程的优先级 419 public final void setPriority(int newPriority) { 420 ThreadGroup g; 421 checkAccess(); 422 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { 423 throw new IllegalArgumentException(); 424 } 425 if ((g = getThreadGroup()) != null) { 426 if (newPriority > g.getMaxPriority()) { 427 newPriority = g.getMaxPriority(); 428 } 429 setPriority0(priority = newPriority); 430 } 431 } 432 433 //返回线程优先级 434 public final int getPriority() { 435 return priority; 436 } 437 438 //设置线程的name 439 public final synchronized void setName(String name) { 440 checkAccess(); 441 this.name = name.toCharArray(); 442 if (threadStatus != 0) { 443 setNativeName(name); 444 } 445 } 446 447 //返回线程的name 448 public final String getName() { 449 return new String(name, true); 450 } 451 452 //返回线程所属的线程组,如果线程已经died,那么会返回null 453 public final ThreadGroup getThreadGroup() { 454 return group; 455 } 456 457 //返回当前线程所在线程组的线程数的估计值 458 public static int activeCount() { 459 return currentThread().getThreadGroup().activeCount(); 460 } 461 462 public static int enumerate(Thread tarray[]) { 463 return currentThread().getThreadGroup().enumerate(tarray); 464 } 465 466 @Deprecated 467 public native int countStackFrames(); 468 469 /* 470 最多等待millis时长当前线程就会死亡,millis=0则要持续等待 471 It is recommended that applications not use {@code wait}, 472 {@code notify}, or {@code notifyAll} on {@code Thread} instances. 473 */ 474 public final synchronized void join(long millis) 475 throws InterruptedException { 476 long base = System.currentTimeMillis(); 477 long now = 0; 478 479 if (millis < 0) { 480 throw new IllegalArgumentException("timeout value is negative"); 481 } 482 483 if (millis == 0) { 484 while (isAlive()) { 485 wait(0); 486 } 487 } else { 488 while (isAlive()) { 489 long delay = millis - now; 490 if (delay <= 0) { 491 break; 492 } 493 wait(delay); 494 now = System.currentTimeMillis() - base; 495 } 496 } 497 } 498 499 //最多等待millis微秒+nanos纳秒时长当前线程就会死亡 500 public final synchronized void join(long millis, int nanos) 501 throws InterruptedException { 502 503 if (millis < 0) { 504 throw new IllegalArgumentException("timeout value is negative"); 505 } 506 507 if (nanos < 0 || nanos > 999999) { 508 throw new IllegalArgumentException( 509 "nanosecond timeout value out of range"); 510 } 511 512 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 513 millis++; 514 } 515 516 join(millis); 517 } 518 519 //等待一直到线程死亡 520 public final void join() throws InterruptedException { 521 join(0); 522 } 523 524 /* 525 Prints a stack trace of the current thread to the standard error stream. 526 This method is used only for debugging. 527 */ 528 public static void dumpStack() { 529 new Exception("Stack trace").printStackTrace(); 530 } 531 532 /* 533 设置当前线程为守护线程或用户线程 534 只有当所有运行中的线程都为守护线程时JVM才会退出 535 setDaemon方法必须在线程调用start方法之前调用 536 */ 537 public final void setDaemon(boolean on) { 538 checkAccess(); 539 if (isAlive()) { 540 throw new IllegalThreadStateException(); 541 } 542 daemon = on; 543 } 544 545 //判断当前线程是否为守护线程 546 public final boolean isDaemon() { 547 return daemon; 548 } 549 550 //确定当前运行线程是否具有修改线程的权限 551 public final void checkAccess() { 552 SecurityManager security = System.getSecurityManager(); 553 if (security != null) { 554 security.checkAccess(this); 555 } 556 } 557 558 public String toString() { 559 ThreadGroup group = getThreadGroup(); 560 if (group != null) { 561 return "Thread[" + getName() + "," + getPriority() + "," + 562 group.getName() + "]"; 563 } else { 564 return "Thread[" + getName() + "," + getPriority() + "," + 565 "" + "]"; 566 } 567 } 568 569 //获取当前线程的ClassLoader 570 @CallerSensitive 571 public ClassLoader getContextClassLoader() { 572 if (contextClassLoader == null) 573 return null; 574 SecurityManager sm = System.getSecurityManager(); 575 if (sm != null) { 576 ClassLoader.checkClassLoaderPermission(contextClassLoader, 577 Reflection.getCallerClass()); 578 } 579 return contextClassLoader; 580 } 581 582 //设置当前线程的ClassLoader 583 public void setContextClassLoader(ClassLoader cl) { 584 SecurityManager sm = System.getSecurityManager(); 585 if (sm != null) { 586 sm.checkPermission(new RuntimePermission("setContextClassLoader")); 587 } 588 contextClassLoader = cl; 589 } 590 591 //当且仅当当前线程持有指定对象的***锁时,返回true,用于断言:assert Thread.holdsLock(obj); 592 public static native boolean holdsLock(Object obj); 593 594 private static final StackTraceElement[] EMPTY_STACK_TRACE 595 = new StackTraceElement[0]; 596 597 /* 598 返回当前线程堆栈转储的堆栈跟踪元素数组 599 如果线程没有start、已经start但没有被调度器调度或已经终止,那么数组长度为0 600 如果数组长度非0,那么数组的第一个元素(索引为0)表示栈的顶部,最后一个元素表示栈底 601 */ 602 public StackTraceElement[] getStackTrace() { 603 if (this != Thread.currentThread()) { 604 SecurityManager security = System.getSecurityManager(); 605 if (security != null) { 606 security.checkPermission( 607 SecurityConstants.GET_STACK_TRACE_PERMISSION); 608 } 609 610 if (!isAlive()) { 611 return EMPTY_STACK_TRACE; 612 } 613 StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[]{this}); 614 StackTraceElement[] stackTrace = stackTraceArray[0]; 615 616 if (stackTrace == null) { 617 stackTrace = EMPTY_STACK_TRACE; 618 } 619 return stackTrace; 620 } else { 621 return (new Exception()).getStackTrace(); 622 } 623 } 624 625 //返回所有存活线程的堆栈跟踪数组的map,由于getAllStackTraces时线程仍在执行,所以得到的结果仅仅是一个快照 626 public static Map<Thread, StackTraceElement[]> getAllStackTraces() { 627 SecurityManager security = System.getSecurityManager(); 628 if (security != null) { 629 security.checkPermission( 630 SecurityConstants.GET_STACK_TRACE_PERMISSION); 631 security.checkPermission( 632 SecurityConstants.MODIFY_THREADGROUP_PERMISSION); 633 } 634 635 Thread[] threads = getThreads(); 636 StackTraceElement[][] traces = dumpThreads(threads); 637 Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length); 638 for (int i = 0; i < threads.length; i++) { 639 StackTraceElement[] stackTrace = traces[i]; 640 if (stackTrace != null) { 641 m.put(threads[i], stackTrace); 642 } 643 } 644 return m; 645 } 646 647 648 private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = 649 new RuntimePermission("enableContextClassLoaderOverride"); 650 651 //Replace with ConcurrentReferenceHashMap when/if it appears in a future release 652 private static class Caches { 653 //子类安全审核结果的缓存 654 static final ConcurrentMap<WeakClassKey, Boolean> subclassAudits = 655 new ConcurrentHashMap<>(); 656 657 //审核子类的弱引用队列 658 static final ReferenceQueue<Class<?>> subclassAuditsQueue = 659 new ReferenceQueue<>(); 660 } 661 662 private static boolean isCCLOverridden(Class<?> cl) { 663 if (cl == Thread.class) 664 return false; 665 666 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); 667 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); 668 Boolean result = Caches.subclassAudits.get(key); 669 if (result == null) { 670 result = Boolean.valueOf(auditSubclass(cl)); 671 Caches.subclassAudits.putIfAbsent(key, result); 672 } 673 674 return result.booleanValue(); 675 } 676 677 private static boolean auditSubclass(final Class<?> subcl) { 678 Boolean result = AccessController.doPrivileged( 679 new PrivilegedAction<Boolean>() { 680 public Boolean run() { 681 for (Class<?> cl = subcl; 682 cl != Thread.class; 683 cl = cl.getSuperclass()) { 684 try { 685 cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]); 686 return Boolean.TRUE; 687 } catch (NoSuchMethodException ex) { 688 } 689 try { 690 Class<?>[] params = {ClassLoader.class}; 691 cl.getDeclaredMethod("setContextClassLoader", params); 692 return Boolean.TRUE; 693 } catch (NoSuchMethodException ex) { 694 } 695 } 696 return Boolean.FALSE; 697 } 698 } 699 ); 700 return result.booleanValue(); 701 } 702 703 private native static StackTraceElement[][] dumpThreads(Thread[] threads); 704 705 private native static Thread[] getThreads(); 706 707 /* 708 返回当前线程的tid,线程的tid是一个在线程创建时生成的long类型正数 709 线程的tid在其生命周期内不会更改且独一无二,当一个线程终止时,tid可以被重用 710 */ 711 public long getId() { 712 return tid; 713 } 714 715 //任一时刻线程只能处于其中的一个状态,且只是虚拟机的状态值,并不会反映操作系统的线程状态 716 public enum State { 717 //线程没有调用start方法之前的状态 718 NEW, 719 720 //线程在JVM里面运行的状态,包括就绪和运行 721 RUNNABLE, 722 723 //线程等待监视器锁的状态 724 BLOCKED, 725 726 /* 727 一个线程等待其他线程的状态,这种等待是无限期的 728 Object.wait with no timeout 729 Thread.join with no timeout 730 LockSupport.park 731 */ 732 WAITING, 733 734 /* 735 一个线程等待其他线程的状态,这种等待是有时间限制的 736 Thread.sleep 737 Object.wait with timeout 738 Thread.join with timeout 739 LockSupport.parkNanos 740 LockSupport.parkUntil 741 */ 742 TIMED_WAITING, 743 744 //线程执行完毕已经退出的状态 745 TERMINATED; 746 } 747 748 //返回当前线程的状态 749 public State getState() { 750 return sun.misc.VM.toThreadState(threadStatus); 751 } 752 753 @FunctionalInterface 754 public interface UncaughtExceptionHandler { 755 void uncaughtException(Thread t, Throwable e); 756 } 757 758 private volatile UncaughtExceptionHandler uncaughtExceptionHandler; 759 760 private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; 761 762 public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 763 SecurityManager sm = System.getSecurityManager(); 764 if (sm != null) { 765 sm.checkPermission( 766 new RuntimePermission("setDefaultUncaughtExceptionHandler") 767 ); 768 } 769 770 defaultUncaughtExceptionHandler = eh; 771 } 772 773 public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { 774 return defaultUncaughtExceptionHandler; 775 } 776 777 public UncaughtExceptionHandler getUncaughtExceptionHandler() { 778 return uncaughtExceptionHandler != null ? 779 uncaughtExceptionHandler : group; 780 } 781 782 public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 783 checkAccess(); 784 uncaughtExceptionHandler = eh; 785 } 786 787 private void dispatchUncaughtException(Throwable e) { 788 getUncaughtExceptionHandler().uncaughtException(this, e); 789 } 790 791 static void processQueue(ReferenceQueue<Class<?>> queue, 792 ConcurrentMap<? extends 793 WeakReference<Class<?>>, ?> map) { 794 Reference<? extends Class<?>> ref; 795 while ((ref = queue.poll()) != null) { 796 map.remove(ref); 797 } 798 } 799 800 static class WeakClassKey extends WeakReference<Class<?>> { 801 private final int hash; 802 803 WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) { 804 super(cl, refQueue); 805 hash = System.identityHashCode(cl); 806 } 807 808 @Override 809 public int hashCode() { 810 return hash; 811 } 812 813 @Override 814 public boolean equals(Object obj) { 815 if (obj == this) 816 return true; 817 818 if (obj instanceof WeakClassKey) { 819 Object referent = get(); 820 return (referent != null) && 821 (referent == ((WeakClassKey) obj).get()); 822 } else { 823 return false; 824 } 825 } 826 } 827 828 @sun.misc.Contended("tlr") 829 long threadLocalRandomSeed; 830 831 @sun.misc.Contended("tlr") 832 int threadLocalRandomProbe; 833 834 @sun.misc.Contended("tlr") 835 int threadLocalRandomSecondarySeed; 836 837 private native void setPriority0(int newPriority); 838 839 private native void stop0(Object o); 840 841 private native void suspend0(); 842 843 private native void resume0(); 844 845 private native void interrupt0(); 846 847 private native void setNativeName(String name); 848 849 }