Programming for thread in Java

Override Annotation

 1 package java.lang;
 2 import java.lang.annotation.ElementType;
 3 import java.lang.annotation.Retention;
 4 import java.lang.annotation.RetentionPolicy;
 5 import java.lang.annotation.Target;
 6 
 7 /**
 8  * Annotation type used to mark methods that override a method declaration in a
 9  * superclass. Compilers produce an error if a method annotated with @Override
10  * does not actually override a method in a superclass.
11  *
12  * @since 1.5
13  */
14 @Target(ElementType.METHOD)
15 @Retention(RetentionPolicy.SOURCE)
16 public @interface Override {
17 }

Runnable Interface

1 package java.lang;
2 /**
3  * Represents a command that can be executed. Often used to run code in a
4  * different {@link Thread}.
5  */
6 public interface Runnable {
7     public void run();
8 }

Thread Class

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

相关文章: