[源码分析]Android消息机制之Thread类

  1 package java.lang;
  2 import dalvik.system.VMStack;
  3 import java.security.AccessController;
  4 import java.util.Map;
  5 import java.util.HashMap;
  6 import org.apache.harmony.security.fortress.SecurityUtils;
  7 public class Thread implements Runnable {
  8     private static final int NANOS_PER_MILLI = 1000000;
  9     private static class ParkState {
 10         private static final int UNPARKED = 1;
 11         private static final int PREEMPTIVELY_UNPARKED = 2;
 12         private static final int PARKED = 3;
 13     }
 14     public enum State {
 15         NEW,
 16         RUNNABLE,
 17         BLOCKED,
 18         WAITING,
 19         TIMED_WAITING,
 20         TERMINATED
 21     }
 22     public final static int MAX_PRIORITY = 10;
 23     public final static int MIN_PRIORITY = 1;
 24     public final static int NORM_PRIORITY = 5;
 25     volatile VMThread vmThread;
 26     volatile ThreadGroup group;
 27     volatile boolean daemon;
 28     volatile String name;
 29     volatile int priority;
 30     volatile long stackSize;
 31     Runnable target;//运行的Runnalbe;
 32     private static int count = 0;
 33     private long id;//线程ID;
 34     ThreadLocal.Values localValues;
 35     ThreadLocal.Values inheritableValues;
 36     private Runnable interruptAction;
 37     private ClassLoader contextClassLoader;
 38     private UncaughtExceptionHandler uncaughtHandler;
 39     private static UncaughtExceptionHandler defaultUncaughtHandler;
 40     boolean hasBeenStarted = false;//是否已经开启;
 41     private int parkState = ParkState.UNPARKED;
 42 
 43     /**
 44      * 不带参数的构造函数;
 45      */
 46     public Thread() {
 47         create(null, null, null, 0);
 48     }
 49     
 50     /**
 51      * 带Runnable的构造函数
 52      */
 53     public Thread(Runnable runnable) {
 54         create(null, runnable, null, 0);
 55     }
 56     
 57     /**
 58      * 带Runnable对象和线程名的构造函数;
 59      */
 60     public Thread(Runnable runnable, String threadName) {
 61         if (threadName == null) {
 62             throw new NullPointerException();
 63         }
 64         create(null, runnable, threadName, 0);
 65     }
 66     
 67     /**
 68      * 带线程名的构造函数;
 69      */
 70     public Thread(String threadName) {
 71         if (threadName == null) {
 72             throw new NullPointerException();
 73         }
 74 
 75         create(null, null, threadName, 0);
 76     }
 77 
 78     /**
 79      * 带线程和Runnable对象的构造函数;
 80      */
 81     public Thread(ThreadGroup group, Runnable runnable) {
 82         create(group, runnable, null, 0);
 83     }
 84     public Thread(ThreadGroup group, Runnable runnable, String threadName) {
 85         if (threadName == null) {
 86             throw new NullPointerException();
 87         }
 88 
 89         create(group, runnable, threadName, 0);
 90     }
 91 
 92     /**
 93      * //带线程和Runnable对象的构造函数;
 94      */
 95     public Thread(ThreadGroup group, String threadName) {
 96         if (threadName == null) {
 97             throw new NullPointerException();
 98         }
 99 
100         create(group, null, threadName, 0);
101     }
102 
103     public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
104         if (threadName == null) {
105             throw new NullPointerException();
106         }
107         create(group, runnable, threadName, stackSize);
108     }
109 
110     Thread(ThreadGroup group, String name, int priority, boolean daemon) {
111         synchronized (Thread.class) {
112             id = ++Thread.count;
113         }
114         //给线程命名;
115         if (name == null) {
116             this.name = "Thread-" + id;
117         } else
118         {
119             this.name = name;
120         }
121 
122         if (group == null) {
123             throw new InternalError("group not specified");
124         }
125         this.group = group;
126         this.target = null;
127         this.stackSize = 0;
128         this.priority = priority;
129         this.daemon = daemon;
130         this.group.addThread(this);
131     }
132     
133     
134     private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
135         SecurityManager smgr = System.getSecurityManager();
136         if (smgr != null) {
137             if (group == null) 
138             {
139                 group = smgr.getThreadGroup();
140             }
141             if (getClass() != Thread.class) 
142             {
143                 Class[] signature = new Class[] { ClassLoader.class 
144             };
145                 try {
146                     getClass().getDeclaredMethod("getContextClassLoader", signature);
147                     smgr.checkPermission(new RuntimePermission("enableContextClassLoaderOverride"));
148                 } catch (NoSuchMethodException ex) {
149                     // Ignore. Just interested in the method's existence.
150                 }
151                 try {
152                     getClass().getDeclaredMethod("setContextClassLoader", signature);
153                     smgr.checkPermission(new RuntimePermission("enableContextClassLoaderOverride"));
154                 } catch (NoSuchMethodException ex) {
155                     // Ignore. Just interested in the method's existence.
156                 }
157             }
158         }
159         /**
160          * 返回一个线程;
161          */
162         Thread currentThread = Thread.currentThread();//实际调用VMThread.currentThread();
163         if (group == null) {
164             group = currentThread.getThreadGroup();
165         }
166         group.checkAccess();
167         if (group.isDestroyed()) {
168             throw new IllegalThreadStateException("Group already destroyed");
169         }
170         this.group = group;
171         synchronized (Thread.class) {//同步,设置线程id;
172             id = ++Thread.count;
173         }
174         if (threadName == null) {
175             this.name = "Thread-" + id;
176         } else {
177             this.name = threadName;
178         }
179         this.target = runnable;//注意这里,是关键;
180         this.stackSize = stackSize;
181         this.priority = currentThread.getPriority();//优先级;
182         this.contextClassLoader = currentThread.contextClassLoader;
183         if (currentThread.inheritableValues != null) {
184             inheritableValues
185                     = new ThreadLocal.Values(currentThread.inheritableValues);
186         }
187         SecurityUtils.putContext(this, AccessController.getContext());
188         this.group.addThread(this);
189     }
190 
191     /**
192      * 获取当前线程数;
193      */
194     public static int activeCount() {
195         return currentThread().getThreadGroup().activeCount();
196     }
197 
198     public final void checkAccess() {
199         SecurityManager currentManager = System.getSecurityManager();
200         if (currentManager != null) {
201             currentManager.checkAccess(this);
202         }
203     }
204 
205     @Deprecated
206     public int countStackFrames() {
207         return getStackTrace().length;
208     }
209 
210     public static Thread currentThread() {
211         return VMThread.currentThread();
212     }
213 
214     @Deprecated
215     public void destroy() {
216         throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize???
217     }
218 
219     public static void dumpStack() {
220         new Throwable("stack dump").printStackTrace();
221     }
222 
223      public static int enumerate(Thread[] threads) {
224         Thread thread = Thread.currentThread();
225         thread.checkAccess();
226         return thread.getThreadGroup().enumerate(threads);
227     }
228 
229     public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
230         SecurityManager securityManager = System.getSecurityManager();
231         if (securityManager != null) {
232             securityManager.checkPermission(new RuntimePermission("getStackTrace"));
233             securityManager.checkPermission(new RuntimePermission("modifyThreadGroup"));
234         }
235         Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>();
236         int count = ThreadGroup.mSystem.activeCount();
237         Thread[] threads = new Thread[count + count / 2];
238 
239         // Enumerate the threads and collect the stacktraces.
240         count = ThreadGroup.mSystem.enumerate(threads);
241         for (int i = 0; i < count; i++) {
242             map.put(threads[i], threads[i].getStackTrace());
243         }
244 
245         return map;
246     }
247     public ClassLoader getContextClassLoader() {
248         SecurityManager sm = System.getSecurityManager();
249         if (sm != null) {
250             ClassLoader calling = VMStack.getCallingClassLoader();
251 
252             if (calling != null && !calling.isAncestorOf(contextClassLoader)) {
253                 sm.checkPermission(new RuntimePermission("getClassLoader"));
254             }
255         }
256 
257         return contextClassLoader;
258     }
259 
260     public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
261         return defaultUncaughtHandler;
262     }
263     public long getId() {
264         return id;
265     }
266 
267     public final String getName() {
268         return name;
269     }
270 
271     public final int getPriority() {
272         return priority;
273     }
274     public StackTraceElement[] getStackTrace() {
275         SecurityManager securityManager = System.getSecurityManager();
276         if (securityManager != null) {
277             securityManager.checkPermission(new RuntimePermission("getStackTrace"));
278         }
279 
280         StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
281         return ste != null ? ste : new StackTraceElement[0];
282     }
283 
284     public State getState() {
285         // TODO This is ugly and should be implemented better.
286         VMThread vmt = this.vmThread;
287 
288         // Make sure we have a valid reference to an object. If native code
289         // deletes the reference we won't run into a null reference later.
290         VMThread thread = vmThread;
291         if (thread != null) {
292             // If the Thread Object became invalid or was not yet started,
293             // getStatus() will return -1.
294             int state = thread.getStatus();
295             if(state != -1) {
296                 return VMThread.STATE_MAP[state];
297             }
298         }
299         return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
300     }
301 
302     public final ThreadGroup getThreadGroup() {
303         // TODO This should actually be done at native termination.
304         if (getState() == Thread.State.TERMINATED) {
305             return null;
306         } else {
307             return group;
308         }
309     }
310 
311     public UncaughtExceptionHandler getUncaughtExceptionHandler() {
312         if (uncaughtHandler != null)
313             return uncaughtHandler;
314         else
315             return group;           // ThreadGroup is instance of UEH
316     }
317 
318     public void interrupt() {
319         checkAccess();
320 
321         if (interruptAction != null) {
322             interruptAction.run();
323         }
324 
325         VMThread vmt = this.vmThread;
326         if (vmt != null) {
327             vmt.interrupt();
328         }
329     }
330 
331     public static boolean interrupted() {
332         return VMThread.interrupted();
333     }
334 
335     public final boolean isAlive() {
336         return (vmThread != null);
337     }
338 
339     public final boolean isDaemon() {
340         return daemon;
341     }
342 
343     public boolean isInterrupted() {
344         VMThread vmt = this.vmThread;
345         if (vmt != null) {
346             return vmt.isInterrupted();
347         }
348 
349         return false;
350     }
351 
352     //强制等待当前线程执行完成;
353     public final void join() throws InterruptedException {
354         VMThread t = vmThread;
355         if (t == null) {
356             return;
357         }
358 
359         synchronized (t) {
360             while (isAlive()) {
361                 t.wait();
362             }
363         }
364     }
365 
366     public final void join(long millis) throws InterruptedException {
367         join(millis, 0);
368     }
369 
370     public final void join(long millis, int nanos) throws InterruptedException {
371         if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) {
372             throw new IllegalArgumentException();
373         }
374 
375         // avoid overflow: if total > 292,277 years, just wait forever
376         boolean overflow = millis >= (Long.MAX_VALUE - nanos) / NANOS_PER_MILLI;
377         boolean forever = (millis | nanos) == 0;
378         if (forever | overflow) {
379             join();
380             return;
381         }
382 
383         VMThread t = vmThread;
384         if (t == null) {
385             return;
386         }
387 
388         synchronized (t) {
389             if (!isAlive()) {
390                 return;
391             }
392 
393             // guaranteed not to overflow
394             long nanosToWait = millis * NANOS_PER_MILLI + nanos;
395 
396             // wait until this thread completes or the timeout has elapsed
397             long start = System.nanoTime();
398             while (true) {
399                 t.wait(millis, nanos);
400                 if (!isAlive()) {
401                     break;
402                 }
403                 long nanosElapsed = System.nanoTime() - start;
404                 long nanosRemaining = nanosToWait - nanosElapsed;
405                 if (nanosRemaining <= 0) {
406                     break;
407                 }
408                 millis = nanosRemaining / NANOS_PER_MILLI;
409                 nanos = (int) (nanosRemaining - millis * NANOS_PER_MILLI);
410             }
411         }
412     }
413 
414     @Deprecated
415     public final void resume() {
416         checkAccess();
417         VMThread vmt = this.vmThread;
418         if (vmt != null) {
419             vmt.resume();
420         }
421     }
422 
423     //调用目标Ruunable的run方法;
424     public void run() {
425         if (target != null) {
426             target.run();
427         }
428     }
429 
430     public void setContextClassLoader(ClassLoader cl) {
431         SecurityManager securityManager = System.getSecurityManager();
432         if (securityManager != null) {
433             securityManager.checkPermission(new RuntimePermission("setContextClassLoader"));
434         }
435 
436         contextClassLoader = cl;
437     }
438 
439     public final void setDaemon(boolean isDaemon) {
440         checkAccess();
441 
442         if (hasBeenStarted) {
443             throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
444         }
445 
446         if (vmThread == null) {
447             daemon = isDaemon;
448         }
449     }
450 
451     public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
452         SecurityManager securityManager = System.getSecurityManager();
453         if (securityManager != null) {
454             securityManager.checkPermission(new RuntimePermission ("setDefaultUncaughtExceptionHandler"));
455         }
456 
457         Thread.defaultUncaughtHandler = handler;
458     }
459 
460     @SuppressWarnings("unused")
461     private void setInterruptAction(Runnable action) {
462         this.interruptAction = action;
463     }
464 
465     public final void setName(String threadName) {
466         if (threadName == null) {
467             throw new NullPointerException();
468         }
469 
470         checkAccess();
471 
472         name = threadName;
473         VMThread vmt = this.vmThread;
474         if (vmt != null) {
475             /* notify the VM that the thread name has changed */
476             vmt.nameChanged(threadName);
477         }
478     }
479 
480     public final void setPriority(int priority) {
481         checkAccess();
482 
483         if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
484             throw new IllegalArgumentException("Prioritiy out of range"); // TODO Externalize?
485         }
486 
487         if (priority > group.getMaxPriority()) {
488             priority = group.getMaxPriority();
489         }
490 
491         this.priority = priority;
492 
493         VMThread vmt = this.vmThread;
494         if (vmt != null) {
495             vmt.setPriority(priority);
496         }
497     }
498 
499     public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
500         checkAccess();
501 
502         uncaughtHandler = handler;
503     }
504 
505 
506     public static void sleep(long time) throws InterruptedException {
507         Thread.sleep(time, 0);
508     }
509 
510     public static void sleep(long millis, int nanos) throws InterruptedException {
511         VMThread.sleep(millis, nanos);
512     }
513 
514     public synchronized void start() {
515         if (hasBeenStarted) {
516             throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
517         }
518 
519         hasBeenStarted = true;
520 
521         VMThread.create(this, stackSize);
522     }
523 
524 
525     @Deprecated
526     public final void stop() {
527         stop(new ThreadDeath());
528     }
529 
530 
531     @Deprecated
532     public final synchronized void stop(Throwable throwable) {
533         SecurityManager securityManager = System.getSecurityManager();
534         if (securityManager != null) {
535             securityManager.checkAccess(this);
536             if (Thread.currentThread() != this) {
537                 securityManager.checkPermission(new RuntimePermission("stopThread"));
538             }
539         }
540 
541         if (throwable == null) {
542             throw new NullPointerException();
543         }
544 
545         VMThread vmt = this.vmThread;
546         if (vmt != null) {
547             vmt.stop(throwable);
548         }
549     }
550 
551 
552     @Deprecated
553     public final void suspend() {
554         checkAccess();
555 
556         VMThread vmt = this.vmThread;
557         if (vmt != null) {
558             vmt.suspend();
559         }
560     }
561 
562 
563     @Override
564     public String toString() {
565         return "Thread[" + name + "," + priority + "," + group.getName() + "]";
566     }
567 
568     public static void yield() {
569         VMThread.yield();
570     }
571 
572 
573 
574     public static boolean holdsLock(Object object) {
575         return currentThread().vmThread.holdsLock(object);
576     }
577 
578 
579     public static interface UncaughtExceptionHandler {
580         /**
581          * The thread is being terminated by an uncaught exception. Further
582          * exceptions thrown in this method are prevent the remainder of the
583          * method from executing, but are otherwise ignored.
584          *
585          * @param thread the thread that has an uncaught exception
586          * @param ex the exception that was thrown
587          *
588          * @since Android 1.0
589          */
590         void uncaughtException(Thread thread, Throwable ex);
591     }
592 
593     /**
594      * Implementation of <code>unpark()</code>. See {@link LangAccessImpl}.
595      */
596     /*package*/ void unpark() {
597         VMThread vmt = vmThread;
598 
599         if (vmt == null) {
600             /*
601              * vmThread is null before the thread is start()ed. In
602              * this case, we just go ahead and set the state to
603              * PREEMPTIVELY_UNPARKED. Since this happens before the
604              * thread is started, we don't have to worry about
605              * synchronizing with it.
606              */
607             parkState = ParkState.PREEMPTIVELY_UNPARKED;
608             return;
609         }
610 
611         synchronized (vmt) {
612             switch (parkState) {
613                 case ParkState.PREEMPTIVELY_UNPARKED: {
614                     /*
615                      * Nothing to do in this case: By definition, a
616                      * preemptively unparked thread is to remain in
617                      * the preemptively unparked state if it is told
618                      * to unpark.
619                      */
620                     break;
621                 }
622                 case ParkState.UNPARKED: {
623                     parkState = ParkState.PREEMPTIVELY_UNPARKED;
624                     break;
625                 }
626                 default /*parked*/: {
627                     parkState = ParkState.UNPARKED;
628                     vmt.notifyAll();
629                     break;
630                 }
631             }
632         }
633     }
634 
635     /*package*/ void parkFor(long nanos) {
636         VMThread vmt = vmThread;
637 
638         if (vmt == null) {
639             // Running threads should always have an associated vmThread.
640             throw new AssertionError();
641         }
642 
643         synchronized (vmt) {
644             switch (parkState) {
645                 case ParkState.PREEMPTIVELY_UNPARKED: {
646                     parkState = ParkState.UNPARKED;
647                     break;
648                 }
649                 case ParkState.UNPARKED: {
650                     long millis = nanos / NANOS_PER_MILLI;
651                     nanos %= NANOS_PER_MILLI;
652 
653                     parkState = ParkState.PARKED;
654                     try {
655                         vmt.wait(millis, (int) nanos);
656                     } catch (InterruptedException ex) {
657                         interrupt();
658                     } finally {
659                         /*
660                          * Note: If parkState manages to become
661                          * PREEMPTIVELY_UNPARKED before hitting this
662                          * code, it should left in that state.
663                          */
664                         if (parkState == ParkState.PARKED) {
665                             parkState = ParkState.UNPARKED;
666                         }
667                     }
668                     break;
669                 }
670                 default /*parked*/: {
671                     throw new AssertionError(
672                             "shouldn't happen: attempt to repark");
673                 }
674             }
675         }
676     }
677 
678     /*package*/ void parkUntil(long time) {
679         VMThread vmt = vmThread;
680 
681         if (vmt == null) {
682             // Running threads should always have an associated vmThread.
683             throw new AssertionError();
684         }
685 
686         synchronized (vmt) {
687             /*
688              * Note: This conflates the two time bases of "wall clock"
689              * time and "monotonic uptime" time. However, given that
690              * the underlying system can only wait on monotonic time,
691              * it is unclear if there is any way to avoid the
692              * conflation. The downside here is that if, having
693              * calculated the delay, the wall clock gets moved ahead,
694              * this method may not return until well after the wall
695              * clock has reached the originally designated time. The
696              * reverse problem (the wall clock being turned back)
697              * isn't a big deal, since this method is allowed to
698              * spuriously return for any reason, and this situation
699              * can safely be construed as just such a spurious return.
700              */
701             long delayMillis = time - System.currentTimeMillis();
702 
703             if (delayMillis <= 0) {
704                 parkState = ParkState.UNPARKED;
705             } else {
706                 parkFor(delayMillis * NANOS_PER_MILLI);
707             }
708         }
709     }
710 }

 

转载于:https://www.cnblogs.com/patui/archive/2013/04/03/2998375.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值