标签:return its channel generate led top mac size RoCE
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 /* 317 This method is called by the system to give a Thread a chance to clean up before it actually exits. 318 */ 319 private void exit() { 320 if (group != null) { 321 group.threadTerminated(this); 322 group = null; 323 } 324 target = null; 325 threadLocals = null; 326 inheritableThreadLocals = null; 327 inheritedAccessControlContext = null; 328 blocker = null; 329 uncaughtExceptionHandler = null; 330 } 331 332 @Deprecated 333 public final void stop() { 334 SecurityManager security = System.getSecurityManager(); 335 if (security != null) { 336 checkAccess(); 337 if (this != Thread.currentThread()) { 338 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); 339 } 340 } 341 if (threadStatus != 0) { 342 resume(); 343 } 344 345 stop0(new ThreadDeath()); 346 } 347 348 @Deprecated 349 public final synchronized void stop(Throwable obj) { 350 throw new UnsupportedOperationException(); 351 } 352 353 /* 354 中断当前线程,如果不是当前线程中断自己,会调用checkAccess方法,这可能会抛出SecurityException 355 1.如果当前线程由于调用wait、join或sleep方法而阻塞,则中断状态会被清除且会抛出InterruptedException 356 2.如果线程由于java.nio.channels.InterruptibleChannel类中的InterruptibleChannel的I/O操作而被阻塞, 357 调用interrupt方法会使通道关闭且线程的中断状态会被重置并抛出ClosedByInterruptException 358 3.如果当前线程由于java.nio.channels.Selector而被阻塞,则线程的中断状态会被重置,且会立即从selection操作 359 返回一个非零值,这就和java.nio.channels.Selector的wakeup()方法被调用一样 360 如果以上条件都不成立,那么线程的中断状态被重置 361 中断一个非活跃线程不产生影响 362 */ 363 public void interrupt() { 364 if (this != Thread.currentThread()) 365 checkAccess(); 366 367 synchronized (blockerLock) { 368 Interruptible b = blocker; 369 if (b != null) { 370 interrupt0(); 371 b.interrupt(this); 372 return; 373 } 374 } 375 interrupt0(); 376 } 377 378 /* 379 测试当前线程是否被中断,并且清除中断状态 380 In other words, if this method were to be called twice in succession, the second 381 call would return false (unless the current thread were interrupted again, after 382 the first call had cleared its interrupted status and before the second call had examined it). 383 384 A thread interruption ignored because a thread was not alive at the time of the interrupt will 385 be reflected by this method returning false. 386 */ 387 public static boolean interrupted() { 388 return currentThread().isInterrupted(true); 389 } 390 391 //测试当前线程是否被中断,但不清除中断状态 392 public boolean isInterrupted() { 393 return isInterrupted(false); 394 } 395 396 private native boolean isInterrupted(boolean ClearInterrupted); 397 398 @Deprecated 399 public void destroy() { 400 throw new NoSuchMethodError(); 401 } 402 403 /* 404 判断线程是否处于存活状态 405 A thread is alive if it has been started and has not yet died. 406 */ 407 public final native boolean isAlive(); 408 409 @Deprecated 410 public final void suspend() { 411 checkAccess(); 412 suspend0(); 413 } 414 415 @Deprecated 416 public final void resume() { 417 checkAccess(); 418 resume0(); 419 } 420 421 //设置线程的优先级 422 public final void setPriority(int newPriority) { 423 ThreadGroup g; 424 checkAccess(); 425 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { 426 throw new IllegalArgumentException(); 427 } 428 if ((g = getThreadGroup()) != null) { 429 if (newPriority > g.getMaxPriority()) { 430 newPriority = g.getMaxPriority(); 431 } 432 setPriority0(priority = newPriority); 433 } 434 } 435 436 //返回线程优先级 437 public final int getPriority() { 438 return priority; 439 } 440 441 //设置线程的name 442 public final synchronized void setName(String name) { 443 checkAccess(); 444 this.name = name.toCharArray(); 445 if (threadStatus != 0) { 446 setNativeName(name); 447 } 448 } 449 450 //返回线程的name 451 public final String getName() { 452 return new String(name, true); 453 } 454 455 /* 456 返回线程所属的线程组,如果线程已经died,那么会返回null 457 */ 458 public final ThreadGroup getThreadGroup() { 459 return group; 460 } 461 462 //返回当前线程所在线程组的线程数的估计值 463 public static int activeCount() { 464 return currentThread().getThreadGroup().activeCount(); 465 } 466 467 public static int enumerate(Thread tarray[]) { 468 return currentThread().getThreadGroup().enumerate(tarray); 469 } 470 471 @Deprecated 472 public native int countStackFrames(); 473 474 /* 475 最多等待millis时长当前线程就会死亡,millis=0则要持续等待 476 It is recommended that applications not use {@code wait}, 477 {@code notify}, or {@code notifyAll} on {@code Thread} instances. 478 */ 479 public final synchronized void join(long millis) 480 throws InterruptedException { 481 long base = System.currentTimeMillis(); 482 long now = 0; 483 484 if (millis < 0) { 485 throw new IllegalArgumentException("timeout value is negative"); 486 } 487 488 if (millis == 0) { 489 while (isAlive()) { 490 wait(0); 491 } 492 } else { 493 while (isAlive()) { 494 long delay = millis - now; 495 if (delay <= 0) { 496 break; 497 } 498 wait(delay); 499 now = System.currentTimeMillis() - base; 500 } 501 } 502 } 503 504 //最多等待millis微秒+nanos纳秒时长当前线程就会死亡 505 public final synchronized void join(long millis, int nanos) 506 throws InterruptedException { 507 508 if (millis < 0) { 509 throw new IllegalArgumentException("timeout value is negative"); 510 } 511 512 if (nanos < 0 || nanos > 999999) { 513 throw new IllegalArgumentException( 514 "nanosecond timeout value out of range"); 515 } 516 517 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 518 millis++; 519 } 520 521 join(millis); 522 } 523 524 //等待一直到线程死亡 525 public final void join() throws InterruptedException { 526 join(0); 527 } 528 529 /* 530 Prints a stack trace of the current thread to the standard error stream. 531 This method is used only for debugging. 532 */ 533 public static void dumpStack() { 534 new Exception("Stack trace").printStackTrace(); 535 } 536 537 /* 538 设置当前线程为守护线程或用户线程 539 只有当所有运行中的线程都为守护线程时JVM才会退出 540 setDaemon方法必须在线程调用start方法之前调用 541 */ 542 public final void setDaemon(boolean on) { 543 checkAccess(); 544 if (isAlive()) { 545 throw new IllegalThreadStateException(); 546 } 547 daemon = on; 548 } 549 550 //判断当前线程是否为守护线程 551 public final boolean isDaemon() { 552 return daemon; 553 } 554 555 //确定当前运行线程是否具有修改线程的权限 556 public final void checkAccess() { 557 SecurityManager security = System.getSecurityManager(); 558 if (security != null) { 559 security.checkAccess(this); 560 } 561 } 562 563 public String toString() { 564 ThreadGroup group = getThreadGroup(); 565 if (group != null) { 566 return "Thread[" + getName() + "," + getPriority() + "," + 567 group.getName() + "]"; 568 } else { 569 return "Thread[" + getName() + "," + getPriority() + "," + 570 "" + "]"; 571 } 572 } 573 574 //获取当前线程的ClassLoader 575 @CallerSensitive 576 public ClassLoader getContextClassLoader() { 577 if (contextClassLoader == null) 578 return null; 579 SecurityManager sm = System.getSecurityManager(); 580 if (sm != null) { 581 ClassLoader.checkClassLoaderPermission(contextClassLoader, 582 Reflection.getCallerClass()); 583 } 584 return contextClassLoader; 585 } 586 587 //设置当前线程的ClassLoader 588 public void setContextClassLoader(ClassLoader cl) { 589 SecurityManager sm = System.getSecurityManager(); 590 if (sm != null) { 591 sm.checkPermission(new RuntimePermission("setContextClassLoader")); 592 } 593 contextClassLoader = cl; 594 } 595 596 /* 597 当且仅当当前线程持有指定对象的监听器锁时,返回true 598 用于断言 assert Thread.holdsLock(obj); 599 */ 600 public static native boolean holdsLock(Object obj); 601 602 private static final StackTraceElement[] EMPTY_STACK_TRACE 603 = new StackTraceElement[0]; 604 605 /* 606 返回当前线程堆栈转储的堆栈跟踪元素数组 607 如果线程没有start、已经start但没有被调度器调度或已经终止,那么数组长度为0 608 如果数组长度非0,那么数组的第一个元素(索引为0)表示栈的顶部,最后一个元素表示栈底 609 */ 610 public StackTraceElement[] getStackTrace() { 611 if (this != Thread.currentThread()) { 612 SecurityManager security = System.getSecurityManager(); 613 if (security != null) { 614 security.checkPermission( 615 SecurityConstants.GET_STACK_TRACE_PERMISSION); 616 } 617 618 if (!isAlive()) { 619 return EMPTY_STACK_TRACE; 620 } 621 StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[]{this}); 622 StackTraceElement[] stackTrace = stackTraceArray[0]; 623 624 if (stackTrace == null) { 625 stackTrace = EMPTY_STACK_TRACE; 626 } 627 return stackTrace; 628 } else { 629 return (new Exception()).getStackTrace(); 630 } 631 } 632 633 //返回所有存活线程的堆栈跟踪数组的map,由于getAllStackTraces时线程仍在执行,所以得到的结果仅仅是一个快照 634 public static Map<Thread, StackTraceElement[]> getAllStackTraces() { 635 SecurityManager security = System.getSecurityManager(); 636 if (security != null) { 637 security.checkPermission( 638 SecurityConstants.GET_STACK_TRACE_PERMISSION); 639 security.checkPermission( 640 SecurityConstants.MODIFY_THREADGROUP_PERMISSION); 641 } 642 643 Thread[] threads = getThreads(); 644 StackTraceElement[][] traces = dumpThreads(threads); 645 Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length); 646 for (int i = 0; i < threads.length; i++) { 647 StackTraceElement[] stackTrace = traces[i]; 648 if (stackTrace != null) { 649 m.put(threads[i], stackTrace); 650 } 651 } 652 return m; 653 } 654 655 656 private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = 657 new RuntimePermission("enableContextClassLoaderOverride"); 658 659 //Replace with ConcurrentReferenceHashMap when/if it appears in a future release 660 private static class Caches { 661 //子类安全审核结果的缓存 662 static final ConcurrentMap<WeakClassKey, Boolean> subclassAudits = 663 new ConcurrentHashMap<>(); 664 665 //审核子类的弱引用队列 666 static final ReferenceQueue<Class<?>> subclassAuditsQueue = 667 new ReferenceQueue<>(); 668 } 669 670 private static boolean isCCLOverridden(Class<?> cl) { 671 if (cl == Thread.class) 672 return false; 673 674 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); 675 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); 676 Boolean result = Caches.subclassAudits.get(key); 677 if (result == null) { 678 result = Boolean.valueOf(auditSubclass(cl)); 679 Caches.subclassAudits.putIfAbsent(key, result); 680 } 681 682 return result.booleanValue(); 683 } 684 685 private static boolean auditSubclass(final Class<?> subcl) { 686 Boolean result = AccessController.doPrivileged( 687 new PrivilegedAction<Boolean>() { 688 public Boolean run() { 689 for (Class<?> cl = subcl; 690 cl != Thread.class; 691 cl = cl.getSuperclass()) { 692 try { 693 cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]); 694 return Boolean.TRUE; 695 } catch (NoSuchMethodException ex) { 696 } 697 try { 698 Class<?>[] params = {ClassLoader.class}; 699 cl.getDeclaredMethod("setContextClassLoader", params); 700 return Boolean.TRUE; 701 } catch (NoSuchMethodException ex) { 702 } 703 } 704 return Boolean.FALSE; 705 } 706 } 707 ); 708 return result.booleanValue(); 709 } 710 711 private native static StackTraceElement[][] dumpThreads(Thread[] threads); 712 713 private native static Thread[] getThreads(); 714 715 /* 716 返回当前线程的tid,线程的tid是一个在线程创建时生成的long类型正数 717 线程的tid在其生命周期内不会更改且独一无二,当一个线程终止时,tid可以被重用 718 */ 719 public long getId() { 720 return tid; 721 } 722 723 //任一时刻线程只能处于其中的一个状态,且只是虚拟机的状态值,并不会反映操作系统的线程状态 724 public enum State { 725 //线程没有调用start方法之前的状态 726 NEW, 727 728 //线程在JVM里面运行的状态,包括就绪和运行 729 RUNNABLE, 730 731 //线程等待监视器锁的状态 732 BLOCKED, 733 734 /* 735 一个线程等待其他线程的状态,这种等待是无限期的 736 Object.wait with no timeout 737 Thread.join with no timeout 738 LockSupport.park 739 */ 740 WAITING, 741 742 /* 743 一个线程等待其他线程的状态,这种等待是有时间限制的 744 Thread.sleep 745 Object.wait with timeout 746 Thread.join with timeout 747 LockSupport.parkNanos 748 LockSupport.parkUntil 749 */ 750 TIMED_WAITING, 751 752 //线程执行完毕已经退出的状态 753 TERMINATED; 754 } 755 756 //返回当前线程的状态 757 public State getState() { 758 return sun.misc.VM.toThreadState(threadStatus); 759 } 760 761 @FunctionalInterface 762 public interface UncaughtExceptionHandler { 763 void uncaughtException(Thread t, Throwable e); 764 } 765 766 private volatile UncaughtExceptionHandler uncaughtExceptionHandler; 767 768 private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; 769 770 public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 771 SecurityManager sm = System.getSecurityManager(); 772 if (sm != null) { 773 sm.checkPermission( 774 new RuntimePermission("setDefaultUncaughtExceptionHandler") 775 ); 776 } 777 778 defaultUncaughtExceptionHandler = eh; 779 } 780 781 public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { 782 return defaultUncaughtExceptionHandler; 783 } 784 785 public UncaughtExceptionHandler getUncaughtExceptionHandler() { 786 return uncaughtExceptionHandler != null ? 787 uncaughtExceptionHandler : group; 788 } 789 790 public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 791 checkAccess(); 792 uncaughtExceptionHandler = eh; 793 } 794 795 private void dispatchUncaughtException(Throwable e) { 796 getUncaughtExceptionHandler().uncaughtException(this, e); 797 } 798 799 static void processQueue(ReferenceQueue<Class<?>> queue, 800 ConcurrentMap<? extends 801 WeakReference<Class<?>>, ?> map) { 802 Reference<? extends Class<?>> ref; 803 while ((ref = queue.poll()) != null) { 804 map.remove(ref); 805 } 806 } 807 808 static class WeakClassKey extends WeakReference<Class<?>> { 809 private final int hash; 810 811 WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) { 812 super(cl, refQueue); 813 hash = System.identityHashCode(cl); 814 } 815 816 @Override 817 public int hashCode() { 818 return hash; 819 } 820 821 @Override 822 public boolean equals(Object obj) { 823 if (obj == this) 824 return true; 825 826 if (obj instanceof WeakClassKey) { 827 Object referent = get(); 828 return (referent != null) && 829 (referent == ((WeakClassKey) obj).get()); 830 } else { 831 return false; 832 } 833 } 834 } 835 836 @sun.misc.Contended("tlr") 837 long threadLocalRandomSeed; 838 839 @sun.misc.Contended("tlr") 840 int threadLocalRandomProbe; 841 842 @sun.misc.Contended("tlr") 843 int threadLocalRandomSecondarySeed; 844 845 private native void setPriority0(int newPriority); 846 847 private native void stop0(Object o); 848 849 private native void suspend0(); 850 851 private native void resume0(); 852 853 private native void interrupt0(); 854 855 private native void setNativeName(String name); 856 }
标签:return its channel generate led top mac size RoCE
原文地址:https://www.cnblogs.com/sakura1027/p/9204545.html