码迷,mamicode.com
首页 > 其他好文 > 详细

死磕JDK源码之Thread

时间:2018-06-20 18:34:55      阅读:271      评论:0      收藏:0      [点我收藏+]

标签: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 }

 

死磕JDK源码之Thread

标签:return   its   channel   generate   led   top   mac   size   RoCE   

原文地址:https://www.cnblogs.com/sakura1027/p/9204545.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!