• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 /*
18  * Copyright (C) 2008 The Android Open Source Project
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *      http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32 
33 package java.lang;
34 
35 import dalvik.system.VMStack;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40 import libcore.util.EmptyArray;
41 
42 /**
43  * A {@code Thread} is a concurrent unit of execution. It has its own call stack
44  * for methods being invoked, their arguments and local variables. Each virtual
45  * machine instance has at least one main {@code Thread} running when it is
46  * started; typically, there are several others for housekeeping. The
47  * application might decide to launch additional {@code Thread}s for specific
48  * purposes.
49  * <p>
50  * {@code Thread}s in the same VM interact and synchronize by the use of shared
51  * objects and monitors associated with these objects. Synchronized methods and
52  * part of the API in {@link Object} also allow {@code Thread}s to cooperate.
53  * <p>
54  * There are basically two main ways of having a {@code Thread} execute
55  * application code. One is providing a new class that extends {@code Thread}
56  * and overriding its {@link #run()} method. The other is providing a new
57  * {@code Thread} instance with a {@link Runnable} object during its creation.
58  * In both cases, the {@link #start()} method must be called to actually execute
59  * the new {@code Thread}.
60  * <p>
61  * Each {@code Thread} has an integer priority that basically determines the
62  * amount of CPU time the {@code Thread} gets. It can be set using the
63  * {@link #setPriority(int)} method. A {@code Thread} can also be made a daemon,
64  * which makes it run in the background. The latter also affects VM termination
65  * behavior: the VM does not terminate automatically as long as there are
66  * non-daemon threads running.
67  *
68  * @see java.lang.Object
69  * @see java.lang.ThreadGroup
70  *
71  */
72 public class Thread implements Runnable {
73     private static final int NANOS_PER_MILLI = 1000000;
74 
75     /** Park states */
76     private static class ParkState {
77         /** park state indicating unparked */
78         private static final int UNPARKED = 1;
79 
80         /** park state indicating preemptively unparked */
81         private static final int PREEMPTIVELY_UNPARKED = 2;
82 
83         /** park state indicating parked */
84         private static final int PARKED = 3;
85     }
86 
87     /**
88      * A representation of a thread's state. A given thread may only be in one
89      * state at a time.
90      */
91     public enum State {
92         /**
93          * The thread has been created, but has never been started.
94          */
95         NEW,
96         /**
97          * The thread may be run.
98          */
99         RUNNABLE,
100         /**
101          * The thread is blocked and waiting for a lock.
102          */
103         BLOCKED,
104         /**
105          * The thread is waiting.
106          */
107         WAITING,
108         /**
109          * The thread is waiting for a specified amount of time.
110          */
111         TIMED_WAITING,
112         /**
113          * The thread has been terminated.
114          */
115         TERMINATED
116     }
117 
118     /**
119      * The maximum priority value allowed for a thread.
120      */
121     public static final int MAX_PRIORITY = 10;
122 
123     /**
124      * The minimum priority value allowed for a thread.
125      */
126     public static final int MIN_PRIORITY = 1;
127 
128     /**
129      * The normal (default) priority value assigned to threads.
130      */
131     public static final int NORM_PRIORITY = 5;
132 
133     /* some of these are accessed directly by the VM; do not rename them */
134     volatile VMThread vmThread;
135     volatile ThreadGroup group;
136     volatile boolean daemon;
137     volatile String name;
138     volatile int priority;
139     volatile long stackSize;
140     Runnable target;
141     private static int count = 0;
142 
143     /**
144      * Holds the thread's ID. We simply count upwards, so
145      * each Thread has a unique ID.
146      */
147     private long id;
148 
149     /**
150      * Normal thread local values.
151      */
152     ThreadLocal.Values localValues;
153 
154     /**
155      * Inheritable thread local values.
156      */
157     ThreadLocal.Values inheritableValues;
158 
159     /** Callbacks to run on interruption. */
160     private final List<Runnable> interruptActions = new ArrayList<Runnable>();
161 
162     /**
163      * Holds the class loader for this Thread, in case there is one.
164      */
165     private ClassLoader contextClassLoader;
166 
167     /**
168      * Holds the handler for uncaught exceptions in this Thread,
169      * in case there is one.
170      */
171     private UncaughtExceptionHandler uncaughtHandler;
172 
173     /**
174      * Holds the default handler for uncaught exceptions, in case there is one.
175      */
176     private static UncaughtExceptionHandler defaultUncaughtHandler;
177 
178     /**
179      * Reflects whether this Thread has already been started. A Thread
180      * can only be started once (no recycling). Also, we need it to deduce
181      * the proper Thread status.
182      */
183     boolean hasBeenStarted = false;
184 
185     /** the park state of the thread */
186     private int parkState = ParkState.UNPARKED;
187 
188     /** The synchronization object responsible for this thread parking. */
189     private Object parkBlocker;
190 
191     /**
192      * Constructs a new {@code Thread} with no {@code Runnable} object and a
193      * newly generated name. The new {@code Thread} will belong to the same
194      * {@code ThreadGroup} as the {@code Thread} calling this constructor.
195      *
196      * @see java.lang.ThreadGroup
197      * @see java.lang.Runnable
198      */
Thread()199     public Thread() {
200         create(null, null, null, 0);
201     }
202 
203     /**
204      * Constructs a new {@code Thread} with a {@code Runnable} object and a
205      * newly generated name. The new {@code Thread} will belong to the same
206      * {@code ThreadGroup} as the {@code Thread} calling this constructor.
207      *
208      * @param runnable
209      *            a {@code Runnable} whose method <code>run</code> will be
210      *            executed by the new {@code Thread}
211      *
212      * @see java.lang.ThreadGroup
213      * @see java.lang.Runnable
214      */
Thread(Runnable runnable)215     public Thread(Runnable runnable) {
216         create(null, runnable, null, 0);
217     }
218 
219     /**
220      * Constructs a new {@code Thread} with a {@code Runnable} object and name
221      * provided. The new {@code Thread} will belong to the same {@code
222      * ThreadGroup} as the {@code Thread} calling this constructor.
223      *
224      * @param runnable
225      *            a {@code Runnable} whose method <code>run</code> will be
226      *            executed by the new {@code Thread}
227      * @param threadName
228      *            the name for the {@code Thread} being created
229      *
230      * @see java.lang.ThreadGroup
231      * @see java.lang.Runnable
232      */
Thread(Runnable runnable, String threadName)233     public Thread(Runnable runnable, String threadName) {
234         if (threadName == null) {
235             throw new NullPointerException();
236         }
237 
238         create(null, runnable, threadName, 0);
239     }
240 
241     /**
242      * Constructs a new {@code Thread} with no {@code Runnable} object and the
243      * name provided. The new {@code Thread} will belong to the same {@code
244      * ThreadGroup} as the {@code Thread} calling this constructor.
245      *
246      * @param threadName
247      *            the name for the {@code Thread} being created
248      *
249      * @see java.lang.ThreadGroup
250      * @see java.lang.Runnable
251      *
252      */
Thread(String threadName)253     public Thread(String threadName) {
254         if (threadName == null) {
255             throw new NullPointerException();
256         }
257 
258         create(null, null, threadName, 0);
259     }
260 
261     /**
262      * Constructs a new {@code Thread} with a {@code Runnable} object and a
263      * newly generated name. The new {@code Thread} will belong to the {@code
264      * ThreadGroup} passed as parameter.
265      *
266      * @param group
267      *            {@code ThreadGroup} to which the new {@code Thread} will
268      *            belong
269      * @param runnable
270      *            a {@code Runnable} whose method <code>run</code> will be
271      *            executed by the new {@code Thread}
272      * @throws IllegalThreadStateException
273      *             if <code>group.destroy()</code> has already been done
274      * @see java.lang.ThreadGroup
275      * @see java.lang.Runnable
276      */
Thread(ThreadGroup group, Runnable runnable)277     public Thread(ThreadGroup group, Runnable runnable) {
278         create(group, runnable, null, 0);
279     }
280 
281     /**
282      * Constructs a new {@code Thread} with a {@code Runnable} object, the given
283      * name and belonging to the {@code ThreadGroup} passed as parameter.
284      *
285      * @param group
286      *            ThreadGroup to which the new {@code Thread} will belong
287      * @param runnable
288      *            a {@code Runnable} whose method <code>run</code> will be
289      *            executed by the new {@code Thread}
290      * @param threadName
291      *            the name for the {@code Thread} being created
292      * @throws IllegalThreadStateException
293      *             if <code>group.destroy()</code> has already been done
294      * @see java.lang.ThreadGroup
295      * @see java.lang.Runnable
296      */
Thread(ThreadGroup group, Runnable runnable, String threadName)297     public Thread(ThreadGroup group, Runnable runnable, String threadName) {
298         if (threadName == null) {
299             throw new NullPointerException();
300         }
301 
302         create(group, runnable, threadName, 0);
303     }
304 
305     /**
306      * Constructs a new {@code Thread} with no {@code Runnable} object, the
307      * given name and belonging to the {@code ThreadGroup} passed as parameter.
308      *
309      * @param group
310      *            {@code ThreadGroup} to which the new {@code Thread} will belong
311      * @param threadName
312      *            the name for the {@code Thread} being created
313      * @throws IllegalThreadStateException
314      *             if <code>group.destroy()</code> has already been done
315      * @see java.lang.ThreadGroup
316      * @see java.lang.Runnable
317      */
Thread(ThreadGroup group, String threadName)318     public Thread(ThreadGroup group, String threadName) {
319         if (threadName == null) {
320             throw new NullPointerException();
321         }
322 
323         create(group, null, threadName, 0);
324     }
325 
326     /**
327      * Constructs a new {@code Thread} with a {@code Runnable} object, the given
328      * name and belonging to the {@code ThreadGroup} passed as parameter.
329      *
330      * @param group
331      *            {@code ThreadGroup} to which the new {@code Thread} will
332      *            belong
333      * @param runnable
334      *            a {@code Runnable} whose method <code>run</code> will be
335      *            executed by the new {@code Thread}
336      * @param threadName
337      *            the name for the {@code Thread} being created
338      * @param stackSize
339      *            a stack size for the new {@code Thread}. This has a highly
340      *            platform-dependent interpretation. It may even be ignored
341      *            completely.
342      * @throws IllegalThreadStateException
343      *             if <code>group.destroy()</code> has already been done
344      * @see java.lang.ThreadGroup
345      * @see java.lang.Runnable
346      */
Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize)347     public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
348         if (threadName == null) {
349             throw new NullPointerException();
350         }
351         create(group, runnable, threadName, stackSize);
352     }
353 
354     /**
355      * Package-scope method invoked by Dalvik VM to create "internal"
356      * threads or attach threads created externally.
357      *
358      * Don't call Thread.currentThread(), since there may not be such
359      * a thing (e.g. for Main).
360      */
Thread(ThreadGroup group, String name, int priority, boolean daemon)361     Thread(ThreadGroup group, String name, int priority, boolean daemon) {
362         synchronized (Thread.class) {
363             id = ++Thread.count;
364         }
365 
366         if (name == null) {
367             this.name = "Thread-" + id;
368         } else {
369             this.name = name;
370         }
371 
372         if (group == null) {
373             throw new InternalError("group not specified");
374         }
375 
376         this.group = group;
377 
378         this.target = null;
379         this.stackSize = 0;
380         this.priority = priority;
381         this.daemon = daemon;
382 
383         /* add ourselves to our ThreadGroup of choice */
384         this.group.addThread(this);
385     }
386 
387     /**
388      * Initializes a new, existing Thread object with a runnable object,
389      * the given name and belonging to the ThreadGroup passed as parameter.
390      * This is the method that the several public constructors delegate their
391      * work to.
392      *
393      * @param group ThreadGroup to which the new Thread will belong
394      * @param runnable a java.lang.Runnable whose method <code>run</code> will
395      *        be executed by the new Thread
396      * @param threadName Name for the Thread being created
397      * @param stackSize Platform dependent stack size
398      * @throws IllegalThreadStateException if <code>group.destroy()</code> has
399      *         already been done
400      * @see java.lang.ThreadGroup
401      * @see java.lang.Runnable
402      */
create(ThreadGroup group, Runnable runnable, String threadName, long stackSize)403     private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
404         Thread currentThread = Thread.currentThread();
405         if (group == null) {
406             group = currentThread.getThreadGroup();
407         }
408 
409         if (group.isDestroyed()) {
410             throw new IllegalThreadStateException("Group already destroyed");
411         }
412 
413         this.group = group;
414 
415         synchronized (Thread.class) {
416             id = ++Thread.count;
417         }
418 
419         if (threadName == null) {
420             this.name = "Thread-" + id;
421         } else {
422             this.name = threadName;
423         }
424 
425         this.target = runnable;
426         this.stackSize = stackSize;
427 
428         this.priority = currentThread.getPriority();
429 
430         this.contextClassLoader = currentThread.contextClassLoader;
431 
432         // Transfer over InheritableThreadLocals.
433         if (currentThread.inheritableValues != null) {
434             inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
435         }
436 
437         // add ourselves to our ThreadGroup of choice
438         this.group.addThread(this);
439     }
440 
441     /**
442      * Returns the number of active {@code Thread}s in the running {@code
443      * Thread}'s group and its subgroups.
444      *
445      * @return the number of {@code Thread}s
446      */
activeCount()447     public static int activeCount() {
448         return currentThread().getThreadGroup().activeCount();
449     }
450 
451     /**
452      * Does nothing.
453      */
checkAccess()454     public final void checkAccess() {
455     }
456 
457     /**
458      * Returns the number of stack frames in this thread.
459      *
460      * @return Number of stack frames
461      * @deprecated The results of this call were never well defined. To make
462      *             things worse, it would depend on whether the Thread was
463      *             suspended or not, and suspend was deprecated too.
464      */
465     @Deprecated
countStackFrames()466     public int countStackFrames() {
467         return getStackTrace().length;
468     }
469 
470     /**
471      * Returns the Thread of the caller, that is, the current Thread.
472      *
473      * @return the current Thread.
474      */
currentThread()475     public static Thread currentThread() {
476         return VMThread.currentThread();
477     }
478 
479     /**
480      * Destroys the receiver without any monitor cleanup.
481      *
482      * @deprecated Not implemented.
483      */
484     @Deprecated
destroy()485     public void destroy() {
486         throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize???
487     }
488 
489     /**
490      * Prints to the standard error stream a text representation of the current
491      * stack for this Thread.
492      *
493      * @see Throwable#printStackTrace()
494      */
dumpStack()495     public static void dumpStack() {
496         new Throwable("stack dump").printStackTrace();
497     }
498 
499     /**
500      * Copies an array with all Threads which are in the same ThreadGroup as the
501      * receiver - and subgroups - into the array <code>threads</code> passed as
502      * parameter. If the array passed as parameter is too small no exception is
503      * thrown - the extra elements are simply not copied.
504      *
505      * @param threads
506      *            array into which the Threads will be copied
507      * @return How many Threads were copied over
508      */
enumerate(Thread[] threads)509     public static int enumerate(Thread[] threads) {
510         Thread thread = Thread.currentThread();
511         return thread.getThreadGroup().enumerate(threads);
512     }
513 
514     /**
515      * Returns a map of all the currently live threads to their stack traces.
516      */
getAllStackTraces()517     public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
518         Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>();
519 
520         // Find out how many live threads we have. Allocate a bit more
521         // space than needed, in case new ones are just being created.
522         int count = ThreadGroup.mSystem.activeCount();
523         Thread[] threads = new Thread[count + count / 2];
524 
525         // Enumerate the threads and collect the stacktraces.
526         count = ThreadGroup.mSystem.enumerate(threads);
527         for (int i = 0; i < count; i++) {
528             map.put(threads[i], threads[i].getStackTrace());
529         }
530 
531         return map;
532     }
533 
534     /**
535      * Returns the context ClassLoader for this Thread.
536      *
537      * @return ClassLoader The context ClassLoader
538      * @see java.lang.ClassLoader
539      * @see #getContextClassLoader()
540      */
getContextClassLoader()541     public ClassLoader getContextClassLoader() {
542         return contextClassLoader;
543     }
544 
545     /**
546      * Returns the default exception handler that's executed when uncaught
547      * exception terminates a thread.
548      *
549      * @return an {@link UncaughtExceptionHandler} or <code>null</code> if
550      *         none exists.
551      */
getDefaultUncaughtExceptionHandler()552     public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
553         return defaultUncaughtHandler;
554     }
555 
556     /**
557      * Returns the thread's identifier. The ID is a positive <code>long</code>
558      * generated on thread creation, is unique to the thread, and doesn't change
559      * during the lifetime of the thread; the ID may be reused after the thread
560      * has been terminated.
561      *
562      * @return the thread's ID.
563      */
getId()564     public long getId() {
565         return id;
566     }
567 
568     /**
569      * Returns the name of the Thread.
570      *
571      * @return the Thread's name
572      */
getName()573     public final String getName() {
574         return name;
575     }
576 
577     /**
578      * Returns the priority of the Thread.
579      *
580      * @return the Thread's priority
581      * @see Thread#setPriority
582      */
getPriority()583     public final int getPriority() {
584         return priority;
585     }
586 
587     /**
588      * Returns an array of {@link StackTraceElement} representing the current thread's stack.
589      */
getStackTrace()590     public StackTraceElement[] getStackTrace() {
591         StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
592         return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
593     }
594 
595     /**
596      * Returns the current state of the Thread. This method is useful for
597      * monitoring purposes.
598      *
599      * @return a {@link State} value.
600      */
getState()601     public State getState() {
602         // TODO This is ugly and should be implemented better.
603         VMThread vmt = this.vmThread;
604 
605         // Make sure we have a valid reference to an object. If native code
606         // deletes the reference we won't run into a null reference later.
607         VMThread thread = vmThread;
608         if (thread != null) {
609             // If the Thread Object became invalid or was not yet started,
610             // getStatus() will return -1.
611             int state = thread.getStatus();
612             if(state != -1) {
613                 return VMThread.STATE_MAP[state];
614             }
615         }
616         return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
617     }
618 
619     /**
620      * Returns the ThreadGroup to which this Thread belongs.
621      *
622      * @return the Thread's ThreadGroup
623      */
getThreadGroup()624     public final ThreadGroup getThreadGroup() {
625         // TODO This should actually be done at native termination.
626         if (getState() == Thread.State.TERMINATED) {
627             return null;
628         } else {
629             return group;
630         }
631     }
632 
633     /**
634      * Returns the thread's uncaught exception handler. If not explicitly set,
635      * then the ThreadGroup's handler is returned. If the thread is terminated,
636      * then <code>null</code> is returned.
637      *
638      * @return an {@link UncaughtExceptionHandler} instance or {@code null}.
639      */
getUncaughtExceptionHandler()640     public UncaughtExceptionHandler getUncaughtExceptionHandler() {
641         if (uncaughtHandler != null)
642             return uncaughtHandler;
643         else
644             return group;           // ThreadGroup is instance of UEH
645     }
646 
647     /**
648      * Posts an interrupt request to this {@code Thread}. The behavior depends on
649      * the state of this {@code Thread}:
650      * <ul>
651      * <li>
652      * {@code Thread}s blocked in one of {@code Object}'s {@code wait()} methods
653      * or one of {@code Thread}'s {@code join()} or {@code sleep()} methods will
654      * be woken up, their interrupt status will be cleared, and they receive an
655      * {@link InterruptedException}.
656      * <li>
657      * {@code Thread}s blocked in an I/O operation of an
658      * {@link java.nio.channels.InterruptibleChannel} will have their interrupt
659      * status set and receive an
660      * {@link java.nio.channels.ClosedByInterruptException}. Also, the channel
661      * will be closed.
662      * <li>
663      * {@code Thread}s blocked in a {@link java.nio.channels.Selector} will have
664      * their interrupt status set and return immediately. They don't receive an
665      * exception in this case.
666      * <ul>
667      *
668      * @see Thread#interrupted
669      * @see Thread#isInterrupted
670      */
interrupt()671     public void interrupt() {
672         synchronized (interruptActions) {
673             for (int i = interruptActions.size() - 1; i >= 0; i--) {
674                 interruptActions.get(i).run();
675             }
676         }
677 
678         VMThread vmt = this.vmThread;
679         if (vmt != null) {
680             vmt.interrupt();
681         }
682     }
683 
684     /**
685      * Returns a <code>boolean</code> indicating whether the current Thread (
686      * <code>currentThread()</code>) has a pending interrupt request (<code>
687      * true</code>) or not (<code>false</code>). It also has the side-effect of
688      * clearing the flag.
689      *
690      * @return a <code>boolean</code> indicating the interrupt status
691      * @see Thread#currentThread
692      * @see Thread#interrupt
693      * @see Thread#isInterrupted
694      */
interrupted()695     public static boolean interrupted() {
696         return VMThread.interrupted();
697     }
698 
699     /**
700      * Returns <code>true</code> if the receiver has already been started and
701      * still runs code (hasn't died yet). Returns <code>false</code> either if
702      * the receiver hasn't been started yet or if it has already started and run
703      * to completion and died.
704      *
705      * @return a <code>boolean</code> indicating the liveness of the Thread
706      * @see Thread#start
707      */
isAlive()708     public final boolean isAlive() {
709         return (vmThread != null);
710     }
711 
712     /**
713      * Returns a <code>boolean</code> indicating whether the receiver is a
714      * daemon Thread (<code>true</code>) or not (<code>false</code>) A
715      * daemon Thread only runs as long as there are non-daemon Threads running.
716      * When the last non-daemon Thread ends, the whole program ends no matter if
717      * it had daemon Threads still running or not.
718      *
719      * @return a <code>boolean</code> indicating whether the Thread is a daemon
720      * @see Thread#setDaemon
721      */
isDaemon()722     public final boolean isDaemon() {
723         return daemon;
724     }
725 
726     /**
727      * Returns a <code>boolean</code> indicating whether the receiver has a
728      * pending interrupt request (<code>true</code>) or not (
729      * <code>false</code>)
730      *
731      * @return a <code>boolean</code> indicating the interrupt status
732      * @see Thread#interrupt
733      * @see Thread#interrupted
734      */
isInterrupted()735     public boolean isInterrupted() {
736         VMThread vmt = this.vmThread;
737         if (vmt != null) {
738             return vmt.isInterrupted();
739         }
740 
741         return false;
742     }
743 
744     /**
745      * Blocks the current Thread (<code>Thread.currentThread()</code>) until
746      * the receiver finishes its execution and dies.
747      *
748      * @throws InterruptedException if <code>interrupt()</code> was called for
749      *         the receiver while it was in the <code>join()</code> call
750      * @see Object#notifyAll
751      * @see java.lang.ThreadDeath
752      */
join()753     public final void join() throws InterruptedException {
754         VMThread t = vmThread;
755         if (t == null) {
756             return;
757         }
758 
759         synchronized (t) {
760             while (isAlive()) {
761                 t.wait();
762             }
763         }
764     }
765 
766     /**
767      * Blocks the current Thread (<code>Thread.currentThread()</code>) until
768      * the receiver finishes its execution and dies or the specified timeout
769      * expires, whatever happens first.
770      *
771      * @param millis The maximum time to wait (in milliseconds).
772      * @throws InterruptedException if <code>interrupt()</code> was called for
773      *         the receiver while it was in the <code>join()</code> call
774      * @see Object#notifyAll
775      * @see java.lang.ThreadDeath
776      */
join(long millis)777     public final void join(long millis) throws InterruptedException {
778         join(millis, 0);
779     }
780 
781     /**
782      * Blocks the current Thread (<code>Thread.currentThread()</code>) until
783      * the receiver finishes its execution and dies or the specified timeout
784      * expires, whatever happens first.
785      *
786      * @param millis The maximum time to wait (in milliseconds).
787      * @param nanos Extra nanosecond precision
788      * @throws InterruptedException if <code>interrupt()</code> was called for
789      *         the receiver while it was in the <code>join()</code> call
790      * @see Object#notifyAll
791      * @see java.lang.ThreadDeath
792      */
join(long millis, int nanos)793     public final void join(long millis, int nanos) throws InterruptedException {
794         if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) {
795             throw new IllegalArgumentException();
796         }
797 
798         // avoid overflow: if total > 292,277 years, just wait forever
799         boolean overflow = millis >= (Long.MAX_VALUE - nanos) / NANOS_PER_MILLI;
800         boolean forever = (millis | nanos) == 0;
801         if (forever | overflow) {
802             join();
803             return;
804         }
805 
806         VMThread t = vmThread;
807         if (t == null) {
808             return;
809         }
810 
811         synchronized (t) {
812             if (!isAlive()) {
813                 return;
814             }
815 
816             // guaranteed not to overflow
817             long nanosToWait = millis * NANOS_PER_MILLI + nanos;
818 
819             // wait until this thread completes or the timeout has elapsed
820             long start = System.nanoTime();
821             while (true) {
822                 t.wait(millis, nanos);
823                 if (!isAlive()) {
824                     break;
825                 }
826                 long nanosElapsed = System.nanoTime() - start;
827                 long nanosRemaining = nanosToWait - nanosElapsed;
828                 if (nanosRemaining <= 0) {
829                     break;
830                 }
831                 millis = nanosRemaining / NANOS_PER_MILLI;
832                 nanos = (int) (nanosRemaining - millis * NANOS_PER_MILLI);
833             }
834         }
835     }
836 
837     /**
838      * Throws {@code UnsupportedOperationException}.
839      *
840      * @see Thread#suspend()
841      * @deprecated Used with deprecated method {@link Thread#suspend}
842      */
843     @Deprecated
resume()844     public final void resume() {
845         throw new UnsupportedOperationException();
846     }
847 
848     /**
849      * Calls the <code>run()</code> method of the Runnable object the receiver
850      * holds. If no Runnable is set, does nothing.
851      *
852      * @see Thread#start
853      */
run()854     public void run() {
855         if (target != null) {
856             target.run();
857         }
858     }
859 
860     /**
861      * Set the context ClassLoader for the receiver.
862      *
863      * @param cl The context ClassLoader
864      * @see #getContextClassLoader()
865      */
setContextClassLoader(ClassLoader cl)866     public void setContextClassLoader(ClassLoader cl) {
867         contextClassLoader = cl;
868     }
869 
870     /**
871      * Set if the receiver is a daemon Thread or not. This can only be done
872      * before the Thread starts running.
873      *
874      * @param isDaemon
875      *            indicates whether the Thread should be daemon or not
876      * @see Thread#isDaemon
877      */
setDaemon(boolean isDaemon)878     public final void setDaemon(boolean isDaemon) {
879         if (hasBeenStarted) {
880             throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
881         }
882 
883         if (vmThread == null) {
884             daemon = isDaemon;
885         }
886     }
887 
888     /**
889      * Sets the default uncaught exception handler. This handler is invoked in
890      * case any Thread dies due to an unhandled exception.
891      *
892      * @param handler
893      *            The handler to set or null.
894      */
setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler)895     public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
896         Thread.defaultUncaughtHandler = handler;
897     }
898 
899     /**
900      * Adds a runnable to be invoked upon interruption. If this thread has
901      * already been interrupted, the runnable will be invoked immediately. The
902      * action should be idempotent as it may be invoked multiple times for a
903      * single interruption.
904      *
905      * <p>Each call to this method must be matched with a corresponding call to
906      * {@link #popInterruptAction$}.
907      *
908      * @hide used by NIO
909      */
pushInterruptAction$(Runnable interruptAction)910     public final void pushInterruptAction$(Runnable interruptAction) {
911         synchronized (interruptActions) {
912             interruptActions.add(interruptAction);
913         }
914 
915         if (interruptAction != null && isInterrupted()) {
916             interruptAction.run();
917         }
918     }
919 
920     /**
921      * Removes {@code interruptAction} so it is not invoked upon interruption.
922      *
923      * @param interruptAction the pushed action, used to check that the call
924      *     stack is correctly nested.
925      *
926      * @hide used by NIO
927      */
popInterruptAction$(Runnable interruptAction)928     public final void popInterruptAction$(Runnable interruptAction) {
929         synchronized (interruptActions) {
930             Runnable removed = interruptActions.remove(interruptActions.size() - 1);
931             if (interruptAction != removed) {
932                 throw new IllegalArgumentException(
933                         "Expected " + interruptAction + " but was " + removed);
934             }
935         }
936     }
937 
938     /**
939      * Sets the name of the Thread.
940      *
941      * @param threadName the new name for the Thread
942      * @see Thread#getName
943      */
setName(String threadName)944     public final void setName(String threadName) {
945         if (threadName == null) {
946             throw new NullPointerException();
947         }
948 
949         name = threadName;
950         VMThread vmt = this.vmThread;
951         if (vmt != null) {
952             /* notify the VM that the thread name has changed */
953             vmt.nameChanged(threadName);
954         }
955     }
956 
957     /**
958      * Sets the priority of the Thread. Note that the final priority set may not
959      * be the parameter that was passed - it will depend on the receiver's
960      * ThreadGroup. The priority cannot be set to be higher than the receiver's
961      * ThreadGroup's maxPriority().
962      *
963      * @param priority
964      *            new priority for the Thread
965      * @throws IllegalArgumentException
966      *             if the new priority is greater than Thread.MAX_PRIORITY or
967      *             less than Thread.MIN_PRIORITY
968      * @see Thread#getPriority
969      */
setPriority(int priority)970     public final void setPriority(int priority) {
971         if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
972             throw new IllegalArgumentException("Priority out of range"); // TODO Externalize?
973         }
974 
975         if (priority > group.getMaxPriority()) {
976             priority = group.getMaxPriority();
977         }
978 
979         this.priority = priority;
980 
981         VMThread vmt = this.vmThread;
982         if (vmt != null) {
983             vmt.setPriority(priority);
984         }
985     }
986 
987     /**
988      * <p>
989      * Sets the uncaught exception handler. This handler is invoked in case this
990      * Thread dies due to an unhandled exception.
991      * </p>
992      *
993      * @param handler
994      *            The handler to set or <code>null</code>.
995      */
setUncaughtExceptionHandler(UncaughtExceptionHandler handler)996     public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
997         uncaughtHandler = handler;
998     }
999 
1000     /**
1001      * Causes the thread which sent this message to sleep for the given interval
1002      * of time (given in milliseconds). The precision is not guaranteed - the
1003      * Thread may sleep more or less than requested.
1004      *
1005      * @param time
1006      *            The time to sleep in milliseconds.
1007      * @throws InterruptedException
1008      *             if <code>interrupt()</code> was called for this Thread while
1009      *             it was sleeping
1010      * @see Thread#interrupt()
1011      */
sleep(long time)1012     public static void sleep(long time) throws InterruptedException {
1013         Thread.sleep(time, 0);
1014     }
1015 
1016     /**
1017      * Causes the thread which sent this message to sleep for the given interval
1018      * of time (given in milliseconds and nanoseconds). The precision is not
1019      * guaranteed - the Thread may sleep more or less than requested.
1020      *
1021      * @param millis
1022      *            The time to sleep in milliseconds.
1023      * @param nanos
1024      *            Extra nanosecond precision
1025      * @throws InterruptedException
1026      *             if <code>interrupt()</code> was called for this Thread while
1027      *             it was sleeping
1028      * @see Thread#interrupt()
1029      */
sleep(long millis, int nanos)1030     public static void sleep(long millis, int nanos) throws InterruptedException {
1031         VMThread.sleep(millis, nanos);
1032     }
1033 
1034     /**
1035      * Starts the new Thread of execution. The <code>run()</code> method of
1036      * the receiver will be called by the receiver Thread itself (and not the
1037      * Thread calling <code>start()</code>).
1038      *
1039      * @throws IllegalThreadStateException if the Thread has been started before
1040      *
1041      * @see Thread#run
1042      */
start()1043     public synchronized void start() {
1044         if (hasBeenStarted) {
1045             throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
1046         }
1047 
1048         hasBeenStarted = true;
1049 
1050         VMThread.create(this, stackSize);
1051     }
1052 
1053     /**
1054      * Requests the receiver Thread to stop and throw ThreadDeath. The Thread is
1055      * resumed if it was suspended and awakened if it was sleeping, so that it
1056      * can proceed to throw ThreadDeath.
1057      *
1058      * @deprecated because stopping a thread in this manner is unsafe and can
1059      * leave your application and the VM in an unpredictable state.
1060      */
1061     @Deprecated
stop()1062     public final void stop() {
1063         stop(new ThreadDeath());
1064     }
1065 
1066     /**
1067      * Throws {@code UnsupportedOperationException}.
1068      *
1069      * @throws NullPointerException if <code>throwable()</code> is
1070      *         <code>null</code>
1071      * @deprecated because stopping a thread in this manner is unsafe and can
1072      * leave your application and the VM in an unpredictable state.
1073      */
1074     @Deprecated
stop(Throwable throwable)1075     public final synchronized void stop(Throwable throwable) {
1076         throw new UnsupportedOperationException();
1077     }
1078 
1079     /**
1080      * Throws {@code UnsupportedOperationException}.
1081      *
1082      * @see Thread#resume()
1083      * @deprecated May cause deadlocks.
1084      */
1085     @Deprecated
suspend()1086     public final void suspend() {
1087         throw new UnsupportedOperationException();
1088     }
1089 
1090     /**
1091      * Returns a string containing a concise, human-readable description of the
1092      * Thread. It includes the Thread's name, priority, and group name.
1093      *
1094      * @return a printable representation for the receiver.
1095      */
1096     @Override
toString()1097     public String toString() {
1098         return "Thread[" + name + "," + priority + "," + group.getName() + "]";
1099     }
1100 
1101     /**
1102      * Causes the calling Thread to yield execution time to another Thread that
1103      * is ready to run. The actual scheduling is implementation-dependent.
1104      */
yield()1105     public static void yield() {
1106         VMThread.yield();
1107     }
1108 
1109     /**
1110      * Indicates whether the current Thread has a monitor lock on the specified
1111      * object.
1112      *
1113      * @param object the object to test for the monitor lock
1114      * @return true if the current thread has a monitor lock on the specified
1115      *         object; false otherwise
1116      */
holdsLock(Object object)1117     public static boolean holdsLock(Object object) {
1118         return currentThread().vmThread.holdsLock(object);
1119     }
1120 
1121     /**
1122      * Implemented by objects that want to handle cases where a thread is being
1123      * terminated by an uncaught exception. Upon such termination, the handler
1124      * is notified of the terminating thread and causal exception. If there is
1125      * no explicit handler set then the thread's group is the default handler.
1126      */
1127     public static interface UncaughtExceptionHandler {
1128         /**
1129          * The thread is being terminated by an uncaught exception. Further
1130          * exceptions thrown in this method are prevent the remainder of the
1131          * method from executing, but are otherwise ignored.
1132          *
1133          * @param thread the thread that has an uncaught exception
1134          * @param ex the exception that was thrown
1135          */
uncaughtException(Thread thread, Throwable ex)1136         void uncaughtException(Thread thread, Throwable ex);
1137     }
1138 
1139     /**
1140      * Unparks this thread. This unblocks the thread it if it was
1141      * previously parked, or indicates that the thread is "preemptively
1142      * unparked" if it wasn't already parked. The latter means that the
1143      * next time the thread is told to park, it will merely clear its
1144      * latent park bit and carry on without blocking.
1145      *
1146      * <p>See {@link java.util.concurrent.locks.LockSupport} for more
1147      * in-depth information of the behavior of this method.</p>
1148      *
1149      * @hide for Unsafe
1150      */
unpark()1151     public void unpark() {
1152         VMThread vmt = vmThread;
1153 
1154         if (vmt == null) {
1155             /*
1156              * vmThread is null before the thread is start()ed. In
1157              * this case, we just go ahead and set the state to
1158              * PREEMPTIVELY_UNPARKED. Since this happens before the
1159              * thread is started, we don't have to worry about
1160              * synchronizing with it.
1161              */
1162             parkState = ParkState.PREEMPTIVELY_UNPARKED;
1163             return;
1164         }
1165 
1166         synchronized (vmt) {
1167             switch (parkState) {
1168                 case ParkState.PREEMPTIVELY_UNPARKED: {
1169                     /*
1170                      * Nothing to do in this case: By definition, a
1171                      * preemptively unparked thread is to remain in
1172                      * the preemptively unparked state if it is told
1173                      * to unpark.
1174                      */
1175                     break;
1176                 }
1177                 case ParkState.UNPARKED: {
1178                     parkState = ParkState.PREEMPTIVELY_UNPARKED;
1179                     break;
1180                 }
1181                 default /*parked*/: {
1182                     parkState = ParkState.UNPARKED;
1183                     vmt.notifyAll();
1184                     break;
1185                 }
1186             }
1187         }
1188     }
1189 
1190     /**
1191      * Parks the current thread for a particular number of nanoseconds, or
1192      * indefinitely. If not indefinitely, this method unparks the thread
1193      * after the given number of nanoseconds if no other thread unparks it
1194      * first. If the thread has been "preemptively unparked," this method
1195      * cancels that unparking and returns immediately. This method may
1196      * also return spuriously (that is, without the thread being told to
1197      * unpark and without the indicated amount of time elapsing).
1198      *
1199      * <p>See {@link java.util.concurrent.locks.LockSupport} for more
1200      * in-depth information of the behavior of this method.</p>
1201      *
1202      * <p>This method must only be called when <code>this</code> is the current
1203      * thread.
1204      *
1205      * @param nanos number of nanoseconds to park for or <code>0</code>
1206      * to park indefinitely
1207      * @throws IllegalArgumentException thrown if <code>nanos &lt; 0</code>
1208      *
1209      * @hide for Unsafe
1210      */
parkFor(long nanos)1211     public void parkFor(long nanos) {
1212         VMThread vmt = vmThread;
1213 
1214         if (vmt == null) {
1215             // Running threads should always have an associated vmThread.
1216             throw new AssertionError();
1217         }
1218 
1219         synchronized (vmt) {
1220             switch (parkState) {
1221                 case ParkState.PREEMPTIVELY_UNPARKED: {
1222                     parkState = ParkState.UNPARKED;
1223                     break;
1224                 }
1225                 case ParkState.UNPARKED: {
1226                     long millis = nanos / NANOS_PER_MILLI;
1227                     nanos %= NANOS_PER_MILLI;
1228 
1229                     parkState = ParkState.PARKED;
1230                     try {
1231                         vmt.wait(millis, (int) nanos);
1232                     } catch (InterruptedException ex) {
1233                         interrupt();
1234                     } finally {
1235                         /*
1236                          * Note: If parkState manages to become
1237                          * PREEMPTIVELY_UNPARKED before hitting this
1238                          * code, it should left in that state.
1239                          */
1240                         if (parkState == ParkState.PARKED) {
1241                             parkState = ParkState.UNPARKED;
1242                         }
1243                     }
1244                     break;
1245                 }
1246                 default /*parked*/: {
1247                     throw new AssertionError(
1248                             "shouldn't happen: attempt to repark");
1249                 }
1250             }
1251         }
1252     }
1253 
1254     /**
1255      * Parks the current thread until the specified system time. This
1256      * method attempts to unpark the current thread immediately after
1257      * <code>System.currentTimeMillis()</code> reaches the specified
1258      * value, if no other thread unparks it first. If the thread has
1259      * been "preemptively unparked," this method cancels that
1260      * unparking and returns immediately. This method may also return
1261      * spuriously (that is, without the thread being told to unpark
1262      * and without the indicated amount of time elapsing).
1263      *
1264      * <p>See {@link java.util.concurrent.locks.LockSupport} for more
1265      * in-depth information of the behavior of this method.</p>
1266      *
1267      * <p>This method must only be called when <code>this</code> is the
1268      * current thread.
1269      *
1270      * @param time the time after which the thread should be unparked,
1271      * in absolute milliseconds-since-the-epoch
1272      *
1273      * @hide for Unsafe
1274      */
parkUntil(long time)1275     public void parkUntil(long time) {
1276         VMThread vmt = vmThread;
1277 
1278         if (vmt == null) {
1279             // Running threads should always have an associated vmThread.
1280             throw new AssertionError();
1281         }
1282 
1283         synchronized (vmt) {
1284             /*
1285              * Note: This conflates the two time bases of "wall clock"
1286              * time and "monotonic uptime" time. However, given that
1287              * the underlying system can only wait on monotonic time,
1288              * it is unclear if there is any way to avoid the
1289              * conflation. The downside here is that if, having
1290              * calculated the delay, the wall clock gets moved ahead,
1291              * this method may not return until well after the wall
1292              * clock has reached the originally designated time. The
1293              * reverse problem (the wall clock being turned back)
1294              * isn't a big deal, since this method is allowed to
1295              * spuriously return for any reason, and this situation
1296              * can safely be construed as just such a spurious return.
1297              */
1298             long delayMillis = time - System.currentTimeMillis();
1299 
1300             if (delayMillis <= 0) {
1301                 parkState = ParkState.UNPARKED;
1302             } else {
1303                 parkFor(delayMillis * NANOS_PER_MILLI);
1304             }
1305         }
1306     }
1307 }
1308