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.security.AccessController; 37 import java.util.HashMap; 38 import java.util.Map; 39 import org.apache.harmony.security.fortress.SecurityUtils; 40 41 /** 42 * A {@code Thread} is a concurrent unit of execution. It has its own call stack 43 * for methods being invoked, their arguments and local variables. Each virtual 44 * machine instance has at least one main {@code Thread} running when it is 45 * started; typically, there are several others for housekeeping. The 46 * application might decide to launch additional {@code Thread}s for specific 47 * purposes. 48 * <p> 49 * {@code Thread}s in the same VM interact and synchronize by the use of shared 50 * objects and monitors associated with these objects. Synchronized methods and 51 * part of the API in {@link Object} also allow {@code Thread}s to cooperate. 52 * <p> 53 * There are basically two main ways of having a {@code Thread} execute 54 * application code. One is providing a new class that extends {@code Thread} 55 * and overriding its {@link #run()} method. The other is providing a new 56 * {@code Thread} instance with a {@link Runnable} object during its creation. 57 * In both cases, the {@link #start()} method must be called to actually execute 58 * the new {@code Thread}. 59 * <p> 60 * Each {@code Thread} has an integer priority that basically determines the 61 * amount of CPU time the {@code Thread} gets. It can be set using the 62 * {@link #setPriority(int)} method. A {@code Thread} can also be made a daemon, 63 * which makes it run in the background. The latter also affects VM termination 64 * behavior: the VM does not terminate automatically as long as there are 65 * non-daemon threads running. 66 * 67 * @see java.lang.Object 68 * @see java.lang.ThreadGroup 69 * 70 */ 71 public class Thread implements Runnable { 72 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 final static int MAX_PRIORITY = 10; 122 123 /** 124 * The minimum priority value allowed for a thread. 125 */ 126 public final static int MIN_PRIORITY = 1; 127 128 /** 129 * The normal (default) priority value assigned to threads. 130 */ 131 public final static 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 /** 160 * Holds the interrupt action for this Thread, if any. 161 * <p> 162 * This is required internally by NIO, so even if it looks like it's 163 * useless, don't delete it! 164 */ 165 private Runnable interruptAction; 166 167 /** 168 * Holds the class loader for this Thread, in case there is one. 169 */ 170 private ClassLoader contextClassLoader; 171 172 /** 173 * Holds the handler for uncaught exceptions in this Thread, 174 * in case there is one. 175 */ 176 private UncaughtExceptionHandler uncaughtHandler; 177 178 /** 179 * Holds the default handler for uncaught exceptions, in case there is one. 180 */ 181 private static UncaughtExceptionHandler defaultUncaughtHandler; 182 183 /** 184 * Reflects whether this Thread has already been started. A Thread 185 * can only be started once (no recycling). Also, we need it to deduce 186 * the proper Thread status. 187 */ 188 boolean hasBeenStarted = false; 189 190 /** the park state of the thread */ 191 private int parkState = ParkState.UNPARKED; 192 193 /** The synchronization object responsible for this thread parking. */ 194 private Object parkBlocker; 195 196 /** 197 * Constructs a new {@code Thread} with no {@code Runnable} object and a 198 * newly generated name. The new {@code Thread} will belong to the same 199 * {@code ThreadGroup} as the {@code Thread} calling this constructor. 200 * 201 * @see java.lang.ThreadGroup 202 * @see java.lang.Runnable 203 */ Thread()204 public Thread() { 205 create(null, null, null, 0); 206 } 207 208 /** 209 * Constructs a new {@code Thread} with a {@code Runnable} object and a 210 * newly generated name. The new {@code Thread} will belong to the same 211 * {@code ThreadGroup} as the {@code Thread} calling this constructor. 212 * 213 * @param runnable 214 * a {@code Runnable} whose method <code>run</code> will be 215 * executed by the new {@code Thread} 216 * 217 * @see java.lang.ThreadGroup 218 * @see java.lang.Runnable 219 */ Thread(Runnable runnable)220 public Thread(Runnable runnable) { 221 create(null, runnable, null, 0); 222 } 223 224 /** 225 * Constructs a new {@code Thread} with a {@code Runnable} object and name 226 * provided. The new {@code Thread} will belong to the same {@code 227 * ThreadGroup} as the {@code Thread} calling this constructor. 228 * 229 * @param runnable 230 * a {@code Runnable} whose method <code>run</code> will be 231 * executed by the new {@code Thread} 232 * @param threadName 233 * the name for the {@code Thread} being created 234 * 235 * @see java.lang.ThreadGroup 236 * @see java.lang.Runnable 237 */ Thread(Runnable runnable, String threadName)238 public Thread(Runnable runnable, String threadName) { 239 if (threadName == null) { 240 throw new NullPointerException(); 241 } 242 243 create(null, runnable, threadName, 0); 244 } 245 246 /** 247 * Constructs a new {@code Thread} with no {@code Runnable} object and the 248 * name provided. The new {@code Thread} will belong to the same {@code 249 * ThreadGroup} as the {@code Thread} calling this constructor. 250 * 251 * @param threadName 252 * the name for the {@code Thread} being created 253 * 254 * @see java.lang.ThreadGroup 255 * @see java.lang.Runnable 256 * 257 */ Thread(String threadName)258 public Thread(String threadName) { 259 if (threadName == null) { 260 throw new NullPointerException(); 261 } 262 263 create(null, null, threadName, 0); 264 } 265 266 /** 267 * Constructs a new {@code Thread} with a {@code Runnable} object and a 268 * newly generated name. The new {@code Thread} will belong to the {@code 269 * ThreadGroup} passed as parameter. 270 * 271 * @param group 272 * {@code ThreadGroup} to which the new {@code Thread} will 273 * belong 274 * @param runnable 275 * a {@code Runnable} whose method <code>run</code> will be 276 * executed by the new {@code Thread} 277 * @throws SecurityException 278 * if <code>group.checkAccess()</code> fails with a 279 * SecurityException 280 * @throws IllegalThreadStateException 281 * if <code>group.destroy()</code> has already been done 282 * @see java.lang.ThreadGroup 283 * @see java.lang.Runnable 284 * @see java.lang.SecurityException 285 * @see java.lang.SecurityManager 286 */ Thread(ThreadGroup group, Runnable runnable)287 public Thread(ThreadGroup group, Runnable runnable) { 288 create(group, runnable, null, 0); 289 } 290 291 /** 292 * Constructs a new {@code Thread} with a {@code Runnable} object, the given 293 * name and belonging to the {@code ThreadGroup} passed as parameter. 294 * 295 * @param group 296 * ThreadGroup to which the new {@code Thread} will belong 297 * @param runnable 298 * a {@code Runnable} whose method <code>run</code> will be 299 * executed by the new {@code Thread} 300 * @param threadName 301 * the name for the {@code Thread} being created 302 * @throws SecurityException 303 * if <code>group.checkAccess()</code> fails with a 304 * SecurityException 305 * @throws IllegalThreadStateException 306 * if <code>group.destroy()</code> has already been done 307 * @see java.lang.ThreadGroup 308 * @see java.lang.Runnable 309 * @see java.lang.SecurityException 310 * @see java.lang.SecurityManager 311 */ Thread(ThreadGroup group, Runnable runnable, String threadName)312 public Thread(ThreadGroup group, Runnable runnable, String threadName) { 313 if (threadName == null) { 314 throw new NullPointerException(); 315 } 316 317 create(group, runnable, threadName, 0); 318 } 319 320 /** 321 * Constructs a new {@code Thread} with no {@code Runnable} object, the 322 * given name and belonging to the {@code ThreadGroup} passed as parameter. 323 * 324 * @param group 325 * {@code ThreadGroup} to which the new {@code Thread} will belong 326 * @param threadName 327 * the name for the {@code Thread} being created 328 * @throws SecurityException 329 * if <code>group.checkAccess()</code> fails with a 330 * SecurityException 331 * @throws IllegalThreadStateException 332 * if <code>group.destroy()</code> has already been done 333 * @see java.lang.ThreadGroup 334 * @see java.lang.Runnable 335 * @see java.lang.SecurityException 336 * @see java.lang.SecurityManager 337 */ Thread(ThreadGroup group, String threadName)338 public Thread(ThreadGroup group, String threadName) { 339 if (threadName == null) { 340 throw new NullPointerException(); 341 } 342 343 create(group, null, threadName, 0); 344 } 345 346 /** 347 * Constructs a new {@code Thread} with a {@code Runnable} object, the given 348 * name and belonging to the {@code ThreadGroup} passed as parameter. 349 * 350 * @param group 351 * {@code ThreadGroup} to which the new {@code Thread} will 352 * belong 353 * @param runnable 354 * a {@code Runnable} whose method <code>run</code> will be 355 * executed by the new {@code Thread} 356 * @param threadName 357 * the name for the {@code Thread} being created 358 * @param stackSize 359 * a stack size for the new {@code Thread}. This has a highly 360 * platform-dependent interpretation. It may even be ignored 361 * completely. 362 * @throws SecurityException 363 * if <code>group.checkAccess()</code> fails with a 364 * SecurityException 365 * @throws IllegalThreadStateException 366 * if <code>group.destroy()</code> has already been done 367 * @see java.lang.ThreadGroup 368 * @see java.lang.Runnable 369 * @see java.lang.SecurityException 370 * @see java.lang.SecurityManager 371 */ Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize)372 public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) { 373 if (threadName == null) { 374 throw new NullPointerException(); 375 } 376 create(group, runnable, threadName, stackSize); 377 } 378 379 /** 380 * Package-scope method invoked by Dalvik VM to create "internal" 381 * threads or attach threads created externally. 382 * 383 * Don't call Thread.currentThread(), since there may not be such 384 * a thing (e.g. for Main). 385 */ Thread(ThreadGroup group, String name, int priority, boolean daemon)386 Thread(ThreadGroup group, String name, int priority, boolean daemon) { 387 synchronized (Thread.class) { 388 id = ++Thread.count; 389 } 390 391 if (name == null) { 392 this.name = "Thread-" + id; 393 } else 394 this.name = name; 395 396 if (group == null) { 397 throw new InternalError("group not specified"); 398 } 399 400 this.group = group; 401 402 this.target = null; 403 this.stackSize = 0; 404 this.priority = priority; 405 this.daemon = daemon; 406 407 /* add ourselves to our ThreadGroup of choice */ 408 this.group.addThread(this); 409 } 410 411 /** 412 * Initializes a new, existing Thread object with a runnable object, 413 * the given name and belonging to the ThreadGroup passed as parameter. 414 * This is the method that the several public constructors delegate their 415 * work to. 416 * 417 * @param group ThreadGroup to which the new Thread will belong 418 * @param runnable a java.lang.Runnable whose method <code>run</code> will 419 * be executed by the new Thread 420 * @param threadName Name for the Thread being created 421 * @param stackSize Platform dependent stack size 422 * @throws SecurityException if <code>group.checkAccess()</code> fails 423 * with a SecurityException 424 * @throws IllegalThreadStateException if <code>group.destroy()</code> has 425 * already been done 426 * @see java.lang.ThreadGroup 427 * @see java.lang.Runnable 428 * @see java.lang.SecurityException 429 * @see java.lang.SecurityManager 430 */ create(ThreadGroup group, Runnable runnable, String threadName, long stackSize)431 private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) { 432 SecurityManager smgr = System.getSecurityManager(); 433 if (smgr != null) { 434 if (group == null) { 435 group = smgr.getThreadGroup(); 436 } 437 438 /* 439 * Freaky security requirement: If the Thread's class is actually 440 * a subclass of Thread and it tries to override either 441 * getContextClassLoader() or setContextClassLoader(), the 442 * SecurityManager has to allow this. 443 */ 444 if (getClass() != Thread.class) { 445 Class[] signature = new Class[] { ClassLoader.class }; 446 447 try { 448 getClass().getDeclaredMethod("getContextClassLoader", signature); 449 smgr.checkPermission(new RuntimePermission("enableContextClassLoaderOverride")); 450 } catch (NoSuchMethodException ex) { 451 // Ignore. Just interested in the method's existence. 452 } 453 454 try { 455 getClass().getDeclaredMethod("setContextClassLoader", signature); 456 smgr.checkPermission(new RuntimePermission("enableContextClassLoaderOverride")); 457 } catch (NoSuchMethodException ex) { 458 // Ignore. Just interested in the method's existence. 459 } 460 } 461 } 462 463 Thread currentThread = Thread.currentThread(); 464 if (group == null) { 465 group = currentThread.getThreadGroup(); 466 } 467 468 group.checkAccess(); 469 if (group.isDestroyed()) { 470 throw new IllegalThreadStateException("Group already destroyed"); 471 } 472 473 this.group = group; 474 475 synchronized (Thread.class) { 476 id = ++Thread.count; 477 } 478 479 if (threadName == null) { 480 this.name = "Thread-" + id; 481 } else { 482 this.name = threadName; 483 } 484 485 this.target = runnable; 486 this.stackSize = stackSize; 487 488 this.priority = currentThread.getPriority(); 489 490 this.contextClassLoader = currentThread.contextClassLoader; 491 492 // Transfer over InheritableThreadLocals. 493 if (currentThread.inheritableValues != null) { 494 inheritableValues 495 = new ThreadLocal.Values(currentThread.inheritableValues); 496 } 497 498 // store current AccessControlContext as inherited context for this thread 499 SecurityUtils.putContext(this, AccessController.getContext()); 500 501 // add ourselves to our ThreadGroup of choice 502 this.group.addThread(this); 503 } 504 505 /** 506 * Returns the number of active {@code Thread}s in the running {@code 507 * Thread}'s group and its subgroups. 508 * 509 * @return the number of {@code Thread}s 510 */ activeCount()511 public static int activeCount() { 512 return currentThread().getThreadGroup().activeCount(); 513 } 514 515 /** 516 * Is used for operations that require approval from a SecurityManager. If 517 * there's none installed, this method is a no-op. If there's a 518 * SecurityManager installed, {@link SecurityManager#checkAccess(Thread)} is 519 * called for that SecurityManager. 520 * 521 * @throws SecurityException 522 * if a SecurityManager is installed and it does not allow 523 * access to the Thread. 524 * 525 * @see java.lang.SecurityException 526 * @see java.lang.SecurityManager 527 */ checkAccess()528 public final void checkAccess() { 529 // Forwards the message to the SecurityManager (if there's one) passing 530 // the receiver as parameter 531 532 SecurityManager currentManager = System.getSecurityManager(); 533 if (currentManager != null) { 534 currentManager.checkAccess(this); 535 } 536 } 537 538 /** 539 * Returns the number of stack frames in this thread. 540 * 541 * @return Number of stack frames 542 * @deprecated The results of this call were never well defined. To make 543 * things worse, it would depend on whether the Thread was 544 * suspended or not, and suspend was deprecated too. 545 */ 546 @Deprecated countStackFrames()547 public int countStackFrames() { 548 return getStackTrace().length; 549 } 550 551 /** 552 * Returns the Thread of the caller, that is, the current Thread. 553 * 554 * @return the current Thread. 555 */ currentThread()556 public static Thread currentThread() { 557 return VMThread.currentThread(); 558 } 559 560 /** 561 * Destroys the receiver without any monitor cleanup. 562 * 563 * @deprecated Not implemented. 564 */ 565 @Deprecated destroy()566 public void destroy() { 567 throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize??? 568 } 569 570 /** 571 * Prints to the standard error stream a text representation of the current 572 * stack for this Thread. 573 * 574 * @see Throwable#printStackTrace() 575 */ dumpStack()576 public static void dumpStack() { 577 new Throwable("stack dump").printStackTrace(); 578 } 579 580 /** 581 * Copies an array with all Threads which are in the same ThreadGroup as the 582 * receiver - and subgroups - into the array <code>threads</code> passed as 583 * parameter. If the array passed as parameter is too small no exception is 584 * thrown - the extra elements are simply not copied. 585 * 586 * @param threads 587 * array into which the Threads will be copied 588 * @return How many Threads were copied over 589 * @throws SecurityException 590 * if the installed SecurityManager fails 591 * {@link SecurityManager#checkAccess(Thread)} 592 * @see java.lang.SecurityException 593 * @see java.lang.SecurityManager 594 */ enumerate(Thread[] threads)595 public static int enumerate(Thread[] threads) { 596 Thread thread = Thread.currentThread(); 597 thread.checkAccess(); 598 return thread.getThreadGroup().enumerate(threads); 599 } 600 601 /** 602 * <p> 603 * Returns the stack traces of all the currently live threads and puts them 604 * into the given map. 605 * </p> 606 * 607 * @return A Map of current Threads to StackTraceElement arrays. 608 * @throws SecurityException 609 * if the current SecurityManager fails the 610 * {@link SecurityManager#checkPermission(java.security.Permission)} 611 * call. 612 */ getAllStackTraces()613 public static Map<Thread, StackTraceElement[]> getAllStackTraces() { 614 SecurityManager securityManager = System.getSecurityManager(); 615 if (securityManager != null) { 616 securityManager.checkPermission(new RuntimePermission("getStackTrace")); 617 securityManager.checkPermission(new RuntimePermission("modifyThreadGroup")); 618 } 619 620 Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>(); 621 622 // Find out how many live threads we have. Allocate a bit more 623 // space than needed, in case new ones are just being created. 624 int count = ThreadGroup.mSystem.activeCount(); 625 Thread[] threads = new Thread[count + count / 2]; 626 627 // Enumerate the threads and collect the stacktraces. 628 count = ThreadGroup.mSystem.enumerate(threads); 629 for (int i = 0; i < count; i++) { 630 map.put(threads[i], threads[i].getStackTrace()); 631 } 632 633 return map; 634 } 635 636 /** 637 * Returns the context ClassLoader for this Thread. 638 * <p> 639 * If the conditions 640 * <ol> 641 * <li>there is a security manager 642 * <li>the caller's class loader is not null 643 * <li>the caller's class loader is not the same as the requested 644 * context class loader and not an ancestor thereof 645 * </ol> 646 * are satisfied, a security check for 647 * <code>RuntimePermission("getClassLoader")</code> is performed first. 648 * 649 * @return ClassLoader The context ClassLoader 650 * @see java.lang.ClassLoader 651 * @see #getContextClassLoader() 652 * 653 * @throws SecurityException 654 * if the aforementioned security check fails. 655 */ getContextClassLoader()656 public ClassLoader getContextClassLoader() { 657 // First, if the conditions 658 // 1) there is a security manager 659 // 2) the caller's class loader is not null 660 // 3) the caller's class loader is not the same as the context 661 // class loader and not an ancestor thereof 662 // are satisfied we should perform a security check. 663 SecurityManager sm = System.getSecurityManager(); 664 if (sm != null) { 665 ClassLoader calling = VMStack.getCallingClassLoader(); 666 667 if (calling != null && !calling.isAncestorOf(contextClassLoader)) { 668 sm.checkPermission(new RuntimePermission("getClassLoader")); 669 } 670 } 671 672 return contextClassLoader; 673 } 674 675 /** 676 * Returns the default exception handler that's executed when uncaught 677 * exception terminates a thread. 678 * 679 * @return an {@link UncaughtExceptionHandler} or <code>null</code> if 680 * none exists. 681 */ getDefaultUncaughtExceptionHandler()682 public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { 683 return defaultUncaughtHandler; 684 } 685 686 /** 687 * Returns the thread's identifier. The ID is a positive <code>long</code> 688 * generated on thread creation, is unique to the thread, and doesn't change 689 * during the lifetime of the thread; the ID may be reused after the thread 690 * has been terminated. 691 * 692 * @return the thread's ID. 693 */ getId()694 public long getId() { 695 return id; 696 } 697 698 /** 699 * Returns the name of the Thread. 700 * 701 * @return the Thread's name 702 */ getName()703 public final String getName() { 704 return name; 705 } 706 707 /** 708 * Returns the priority of the Thread. 709 * 710 * @return the Thread's priority 711 * @see Thread#setPriority 712 */ getPriority()713 public final int getPriority() { 714 return priority; 715 } 716 717 /** 718 * Returns the a stack trace representing the current execution state of 719 * this Thread. 720 * <p> 721 * The <code>RuntimePermission("getStackTrace")</code> is checked before 722 * returning a result. 723 * </p> 724 * 725 * @return an array of StackTraceElements. 726 * @throws SecurityException 727 * if the current SecurityManager fails the 728 * {@link SecurityManager#checkPermission(java.security.Permission)} 729 * call. 730 */ getStackTrace()731 public StackTraceElement[] getStackTrace() { 732 SecurityManager securityManager = System.getSecurityManager(); 733 if (securityManager != null) { 734 securityManager.checkPermission(new RuntimePermission("getStackTrace")); 735 } 736 737 StackTraceElement ste[] = VMStack.getThreadStackTrace(this); 738 return ste != null ? ste : new StackTraceElement[0]; 739 } 740 741 /** 742 * Returns the current state of the Thread. This method is useful for 743 * monitoring purposes. 744 * 745 * @return a {@link State} value. 746 */ getState()747 public State getState() { 748 // TODO This is ugly and should be implemented better. 749 VMThread vmt = this.vmThread; 750 751 // Make sure we have a valid reference to an object. If native code 752 // deletes the reference we won't run into a null reference later. 753 VMThread thread = vmThread; 754 if (thread != null) { 755 // If the Thread Object became invalid or was not yet started, 756 // getStatus() will return -1. 757 int state = thread.getStatus(); 758 if(state != -1) { 759 return VMThread.STATE_MAP[state]; 760 } 761 } 762 return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW; 763 } 764 765 /** 766 * Returns the ThreadGroup to which this Thread belongs. 767 * 768 * @return the Thread's ThreadGroup 769 */ getThreadGroup()770 public final ThreadGroup getThreadGroup() { 771 // TODO This should actually be done at native termination. 772 if (getState() == Thread.State.TERMINATED) { 773 return null; 774 } else { 775 return group; 776 } 777 } 778 779 /** 780 * Returns the thread's uncaught exception handler. If not explicitly set, 781 * then the ThreadGroup's handler is returned. If the thread is terminated, 782 * then <code>null</code> is returned. 783 * 784 * @return an {@link UncaughtExceptionHandler} instance or {@code null}. 785 */ getUncaughtExceptionHandler()786 public UncaughtExceptionHandler getUncaughtExceptionHandler() { 787 if (uncaughtHandler != null) 788 return uncaughtHandler; 789 else 790 return group; // ThreadGroup is instance of UEH 791 } 792 793 /** 794 * Posts an interrupt request to this {@code Thread}. Unless the caller is 795 * the {@link #currentThread()}, the method {@code checkAccess()} is called 796 * for the installed {@code SecurityManager}, if any. This may result in a 797 * {@code SecurityException} being thrown. The further behavior depends on 798 * the state of this {@code Thread}: 799 * <ul> 800 * <li> 801 * {@code Thread}s blocked in one of {@code Object}'s {@code wait()} methods 802 * or one of {@code Thread}'s {@code join()} or {@code sleep()} methods will 803 * be woken up, their interrupt status will be cleared, and they receive an 804 * {@link InterruptedException}. 805 * <li> 806 * {@code Thread}s blocked in an I/O operation of an 807 * {@link java.nio.channels.InterruptibleChannel} will have their interrupt 808 * status set and receive an 809 * {@link java.nio.channels.ClosedByInterruptException}. Also, the channel 810 * will be closed. 811 * <li> 812 * {@code Thread}s blocked in a {@link java.nio.channels.Selector} will have 813 * their interrupt status set and return immediately. They don't receive an 814 * exception in this case. 815 * <ul> 816 * 817 * @throws SecurityException 818 * if <code>checkAccess()</code> fails with a SecurityException 819 * @see java.lang.SecurityException 820 * @see java.lang.SecurityManager 821 * @see Thread#interrupted 822 * @see Thread#isInterrupted 823 */ interrupt()824 public void interrupt() { 825 checkAccess(); 826 827 if (interruptAction != null) { 828 interruptAction.run(); 829 } 830 831 VMThread vmt = this.vmThread; 832 if (vmt != null) { 833 vmt.interrupt(); 834 } 835 } 836 837 /** 838 * Returns a <code>boolean</code> indicating whether the current Thread ( 839 * <code>currentThread()</code>) has a pending interrupt request (<code> 840 * true</code>) or not (<code>false</code>). It also has the side-effect of 841 * clearing the flag. 842 * 843 * @return a <code>boolean</code> indicating the interrupt status 844 * @see Thread#currentThread 845 * @see Thread#interrupt 846 * @see Thread#isInterrupted 847 */ interrupted()848 public static boolean interrupted() { 849 return VMThread.interrupted(); 850 } 851 852 /** 853 * Returns <code>true</code> if the receiver has already been started and 854 * still runs code (hasn't died yet). Returns <code>false</code> either if 855 * the receiver hasn't been started yet or if it has already started and run 856 * to completion and died. 857 * 858 * @return a <code>boolean</code> indicating the liveness of the Thread 859 * @see Thread#start 860 */ isAlive()861 public final boolean isAlive() { 862 return (vmThread != null); 863 } 864 865 /** 866 * Returns a <code>boolean</code> indicating whether the receiver is a 867 * daemon Thread (<code>true</code>) or not (<code>false</code>) A 868 * daemon Thread only runs as long as there are non-daemon Threads running. 869 * When the last non-daemon Thread ends, the whole program ends no matter if 870 * it had daemon Threads still running or not. 871 * 872 * @return a <code>boolean</code> indicating whether the Thread is a daemon 873 * @see Thread#setDaemon 874 */ isDaemon()875 public final boolean isDaemon() { 876 return daemon; 877 } 878 879 /** 880 * Returns a <code>boolean</code> indicating whether the receiver has a 881 * pending interrupt request (<code>true</code>) or not ( 882 * <code>false</code>) 883 * 884 * @return a <code>boolean</code> indicating the interrupt status 885 * @see Thread#interrupt 886 * @see Thread#interrupted 887 */ isInterrupted()888 public boolean isInterrupted() { 889 VMThread vmt = this.vmThread; 890 if (vmt != null) { 891 return vmt.isInterrupted(); 892 } 893 894 return false; 895 } 896 897 /** 898 * Blocks the current Thread (<code>Thread.currentThread()</code>) until 899 * the receiver finishes its execution and dies. 900 * 901 * @throws InterruptedException if <code>interrupt()</code> was called for 902 * the receiver while it was in the <code>join()</code> call 903 * @see Object#notifyAll 904 * @see java.lang.ThreadDeath 905 */ join()906 public final void join() throws InterruptedException { 907 VMThread t = vmThread; 908 if (t == null) { 909 return; 910 } 911 912 synchronized (t) { 913 while (isAlive()) { 914 t.wait(); 915 } 916 } 917 } 918 919 /** 920 * Blocks the current Thread (<code>Thread.currentThread()</code>) until 921 * the receiver finishes its execution and dies or the specified timeout 922 * expires, whatever happens first. 923 * 924 * @param millis The maximum time to wait (in milliseconds). 925 * @throws InterruptedException if <code>interrupt()</code> was called for 926 * the receiver while it was in the <code>join()</code> call 927 * @see Object#notifyAll 928 * @see java.lang.ThreadDeath 929 */ join(long millis)930 public final void join(long millis) throws InterruptedException { 931 join(millis, 0); 932 } 933 934 /** 935 * Blocks the current Thread (<code>Thread.currentThread()</code>) until 936 * the receiver finishes its execution and dies or the specified timeout 937 * expires, whatever happens first. 938 * 939 * @param millis The maximum time to wait (in milliseconds). 940 * @param nanos Extra nanosecond precision 941 * @throws InterruptedException if <code>interrupt()</code> was called for 942 * the receiver while it was in the <code>join()</code> call 943 * @see Object#notifyAll 944 * @see java.lang.ThreadDeath 945 */ join(long millis, int nanos)946 public final void join(long millis, int nanos) throws InterruptedException { 947 if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) { 948 throw new IllegalArgumentException(); 949 } 950 951 // avoid overflow: if total > 292,277 years, just wait forever 952 boolean overflow = millis >= (Long.MAX_VALUE - nanos) / NANOS_PER_MILLI; 953 boolean forever = (millis | nanos) == 0; 954 if (forever | overflow) { 955 join(); 956 return; 957 } 958 959 VMThread t = vmThread; 960 if (t == null) { 961 return; 962 } 963 964 synchronized (t) { 965 if (!isAlive()) { 966 return; 967 } 968 969 // guaranteed not to overflow 970 long nanosToWait = millis * NANOS_PER_MILLI + nanos; 971 972 // wait until this thread completes or the timeout has elapsed 973 long start = System.nanoTime(); 974 while (true) { 975 t.wait(millis, nanos); 976 if (!isAlive()) { 977 break; 978 } 979 long nanosElapsed = System.nanoTime() - start; 980 long nanosRemaining = nanosToWait - nanosElapsed; 981 if (nanosRemaining <= 0) { 982 break; 983 } 984 millis = nanosRemaining / NANOS_PER_MILLI; 985 nanos = (int) (nanosRemaining - millis * NANOS_PER_MILLI); 986 } 987 } 988 } 989 990 /** 991 * Resumes a suspended Thread. This is a no-op if the receiver was never 992 * suspended, or suspended and already resumed. If the receiver is 993 * suspended, however, makes it resume to the point where it was when it was 994 * suspended. 995 * 996 * @throws SecurityException 997 * if <code>checkAccess()</code> fails with a SecurityException 998 * @see Thread#suspend() 999 * @deprecated Used with deprecated method {@link Thread#suspend} 1000 */ 1001 @Deprecated resume()1002 public final void resume() { 1003 checkAccess(); 1004 1005 VMThread vmt = this.vmThread; 1006 if (vmt != null) { 1007 vmt.resume(); 1008 } 1009 } 1010 1011 /** 1012 * Calls the <code>run()</code> method of the Runnable object the receiver 1013 * holds. If no Runnable is set, does nothing. 1014 * 1015 * @see Thread#start 1016 */ run()1017 public void run() { 1018 if (target != null) { 1019 target.run(); 1020 } 1021 } 1022 1023 /** 1024 * Set the context ClassLoader for the receiver. 1025 * <p> 1026 * The <code>RuntimePermission("setContextClassLoader")</code> 1027 * is checked prior to setting the handler. 1028 * </p> 1029 * 1030 * @param cl The context ClassLoader 1031 * @throws SecurityException if the current SecurityManager fails the 1032 * checkPermission call. 1033 * @see java.lang.ClassLoader 1034 * @see #getContextClassLoader() 1035 */ setContextClassLoader(ClassLoader cl)1036 public void setContextClassLoader(ClassLoader cl) { 1037 SecurityManager securityManager = System.getSecurityManager(); 1038 if (securityManager != null) { 1039 securityManager.checkPermission(new RuntimePermission("setContextClassLoader")); 1040 } 1041 1042 contextClassLoader = cl; 1043 } 1044 1045 /** 1046 * Set if the receiver is a daemon Thread or not. This can only be done 1047 * before the Thread starts running. 1048 * 1049 * @param isDaemon 1050 * indicates whether the Thread should be daemon or not 1051 * @throws SecurityException 1052 * if <code>checkAccess()</code> fails with a SecurityException 1053 * @see Thread#isDaemon 1054 */ setDaemon(boolean isDaemon)1055 public final void setDaemon(boolean isDaemon) { 1056 checkAccess(); 1057 1058 if (hasBeenStarted) { 1059 throw new IllegalThreadStateException("Thread already started."); // TODO Externalize? 1060 } 1061 1062 if (vmThread == null) { 1063 daemon = isDaemon; 1064 } 1065 } 1066 1067 /** 1068 * <p> 1069 * Sets the default uncaught exception handler. This handler is invoked in 1070 * case any Thread dies due to an unhandled exception. 1071 * </p> 1072 * <p> 1073 * The <code>RuntimePermission("setDefaultUncaughtExceptionHandler")</code> 1074 * is checked prior to setting the handler. 1075 * </p> 1076 * 1077 * @param handler 1078 * The handler to set or <code>null</code>. 1079 * @throws SecurityException 1080 * if the current SecurityManager fails the checkPermission 1081 * call. 1082 */ setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler)1083 public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) { 1084 SecurityManager securityManager = System.getSecurityManager(); 1085 if (securityManager != null) { 1086 securityManager.checkPermission(new RuntimePermission ("setDefaultUncaughtExceptionHandler")); 1087 } 1088 1089 Thread.defaultUncaughtHandler = handler; 1090 } 1091 1092 /** 1093 * Set the action to be executed when interruption, which is probably be 1094 * used to implement the interruptible channel. The action is null by 1095 * default. And if this method is invoked by passing in a non-null value, 1096 * this action's run() method will be invoked in <code>interrupt()</code>. 1097 * <p> 1098 * This is required internally by NIO, so even if it looks like it's 1099 * useless, don't delete it! 1100 * 1101 * @param action the action to be executed when interruption 1102 */ 1103 @SuppressWarnings("unused") setInterruptAction(Runnable action)1104 private void setInterruptAction(Runnable action) { 1105 this.interruptAction = action; 1106 } 1107 1108 /** 1109 * Sets the name of the Thread. 1110 * 1111 * @param threadName the new name for the Thread 1112 * @throws SecurityException if <code>checkAccess()</code> fails with a 1113 * SecurityException 1114 * @see Thread#getName 1115 */ setName(String threadName)1116 public final void setName(String threadName) { 1117 if (threadName == null) { 1118 throw new NullPointerException(); 1119 } 1120 1121 checkAccess(); 1122 1123 name = threadName; 1124 VMThread vmt = this.vmThread; 1125 if (vmt != null) { 1126 /* notify the VM that the thread name has changed */ 1127 vmt.nameChanged(threadName); 1128 } 1129 } 1130 1131 /** 1132 * Sets the priority of the Thread. Note that the final priority set may not 1133 * be the parameter that was passed - it will depend on the receiver's 1134 * ThreadGroup. The priority cannot be set to be higher than the receiver's 1135 * ThreadGroup's maxPriority(). 1136 * 1137 * @param priority 1138 * new priority for the Thread 1139 * @throws SecurityException 1140 * if <code>checkAccess()</code> fails with a SecurityException 1141 * @throws IllegalArgumentException 1142 * if the new priority is greater than Thread.MAX_PRIORITY or 1143 * less than Thread.MIN_PRIORITY 1144 * @see Thread#getPriority 1145 */ setPriority(int priority)1146 public final void setPriority(int priority) { 1147 checkAccess(); 1148 1149 if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) { 1150 throw new IllegalArgumentException("Priority out of range"); // TODO Externalize? 1151 } 1152 1153 if (priority > group.getMaxPriority()) { 1154 priority = group.getMaxPriority(); 1155 } 1156 1157 this.priority = priority; 1158 1159 VMThread vmt = this.vmThread; 1160 if (vmt != null) { 1161 vmt.setPriority(priority); 1162 } 1163 } 1164 1165 /** 1166 * <p> 1167 * Sets the uncaught exception handler. This handler is invoked in case this 1168 * Thread dies due to an unhandled exception. 1169 * </p> 1170 * 1171 * @param handler 1172 * The handler to set or <code>null</code>. 1173 * @throws SecurityException 1174 * if the current SecurityManager fails the checkAccess call. 1175 */ setUncaughtExceptionHandler(UncaughtExceptionHandler handler)1176 public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) { 1177 checkAccess(); 1178 1179 uncaughtHandler = handler; 1180 } 1181 1182 /** 1183 * Causes the thread which sent this message to sleep for the given interval 1184 * of time (given in milliseconds). The precision is not guaranteed - the 1185 * Thread may sleep more or less than requested. 1186 * 1187 * @param time 1188 * The time to sleep in milliseconds. 1189 * @throws InterruptedException 1190 * if <code>interrupt()</code> was called for this Thread while 1191 * it was sleeping 1192 * @see Thread#interrupt() 1193 */ sleep(long time)1194 public static void sleep(long time) throws InterruptedException { 1195 Thread.sleep(time, 0); 1196 } 1197 1198 /** 1199 * Causes the thread which sent this message to sleep for the given interval 1200 * of time (given in milliseconds and nanoseconds). The precision is not 1201 * guaranteed - the Thread may sleep more or less than requested. 1202 * 1203 * @param millis 1204 * The time to sleep in milliseconds. 1205 * @param nanos 1206 * Extra nanosecond precision 1207 * @throws InterruptedException 1208 * if <code>interrupt()</code> was called for this Thread while 1209 * it was sleeping 1210 * @see Thread#interrupt() 1211 */ sleep(long millis, int nanos)1212 public static void sleep(long millis, int nanos) throws InterruptedException { 1213 VMThread.sleep(millis, nanos); 1214 } 1215 1216 /** 1217 * Starts the new Thread of execution. The <code>run()</code> method of 1218 * the receiver will be called by the receiver Thread itself (and not the 1219 * Thread calling <code>start()</code>). 1220 * 1221 * @throws IllegalThreadStateException if the Thread has been started before 1222 * 1223 * @see Thread#run 1224 */ start()1225 public synchronized void start() { 1226 if (hasBeenStarted) { 1227 throw new IllegalThreadStateException("Thread already started."); // TODO Externalize? 1228 } 1229 1230 hasBeenStarted = true; 1231 1232 VMThread.create(this, stackSize); 1233 } 1234 1235 /** 1236 * Requests the receiver Thread to stop and throw ThreadDeath. The Thread is 1237 * resumed if it was suspended and awakened if it was sleeping, so that it 1238 * can proceed to throw ThreadDeath. 1239 * 1240 * @throws SecurityException if <code>checkAccess()</code> fails with a 1241 * SecurityException 1242 * @deprecated because stopping a thread in this manner is unsafe and can 1243 * leave your application and the VM in an unpredictable state. 1244 */ 1245 @Deprecated stop()1246 public final void stop() { 1247 stop(new ThreadDeath()); 1248 } 1249 1250 /** 1251 * Requests the receiver Thread to stop and throw the 1252 * <code>throwable()</code>. The Thread is resumed if it was suspended 1253 * and awakened if it was sleeping, so that it can proceed to throw the 1254 * <code>throwable()</code>. 1255 * 1256 * @param throwable Throwable object to be thrown by the Thread 1257 * @throws SecurityException if <code>checkAccess()</code> fails with a 1258 * SecurityException 1259 * @throws NullPointerException if <code>throwable()</code> is 1260 * <code>null</code> 1261 * @deprecated because stopping a thread in this manner is unsafe and can 1262 * leave your application and the VM in an unpredictable state. 1263 */ 1264 @Deprecated stop(Throwable throwable)1265 public final synchronized void stop(Throwable throwable) { 1266 SecurityManager securityManager = System.getSecurityManager(); 1267 if (securityManager != null) { 1268 securityManager.checkAccess(this); 1269 if (Thread.currentThread() != this) { 1270 securityManager.checkPermission(new RuntimePermission("stopThread")); 1271 } 1272 } 1273 1274 if (throwable == null) { 1275 throw new NullPointerException(); 1276 } 1277 1278 VMThread vmt = this.vmThread; 1279 if (vmt != null) { 1280 vmt.stop(throwable); 1281 } 1282 } 1283 1284 /** 1285 * Suspends this Thread. This is a no-op if the receiver is suspended. If 1286 * the receiver <code>isAlive()</code> however, suspended it until <code> 1287 * resume()</code> is sent to it. Suspend requests are not queued, which 1288 * means that N requests are equivalent to just one - only one resume 1289 * request is needed in this case. 1290 * 1291 * @throws SecurityException 1292 * if <code>checkAccess()</code> fails with a SecurityException 1293 * @see Thread#resume() 1294 * @deprecated May cause deadlocks. 1295 */ 1296 @Deprecated suspend()1297 public final void suspend() { 1298 checkAccess(); 1299 1300 VMThread vmt = this.vmThread; 1301 if (vmt != null) { 1302 vmt.suspend(); 1303 } 1304 } 1305 1306 /** 1307 * Returns a string containing a concise, human-readable description of the 1308 * Thread. It includes the Thread's name, priority, and group name. 1309 * 1310 * @return a printable representation for the receiver. 1311 */ 1312 @Override toString()1313 public String toString() { 1314 return "Thread[" + name + "," + priority + "," + group.getName() + "]"; 1315 } 1316 1317 /** 1318 * Causes the calling Thread to yield execution time to another Thread that 1319 * is ready to run. The actual scheduling is implementation-dependent. 1320 */ yield()1321 public static void yield() { 1322 VMThread.yield(); 1323 } 1324 1325 /** 1326 * Indicates whether the current Thread has a monitor lock on the specified 1327 * object. 1328 * 1329 * @param object the object to test for the monitor lock 1330 * @return true if the current thread has a monitor lock on the specified 1331 * object; false otherwise 1332 */ holdsLock(Object object)1333 public static boolean holdsLock(Object object) { 1334 return currentThread().vmThread.holdsLock(object); 1335 } 1336 1337 /** 1338 * Implemented by objects that want to handle cases where a thread is being 1339 * terminated by an uncaught exception. Upon such termination, the handler 1340 * is notified of the terminating thread and causal exception. If there is 1341 * no explicit handler set then the thread's group is the default handler. 1342 */ 1343 public static interface UncaughtExceptionHandler { 1344 /** 1345 * The thread is being terminated by an uncaught exception. Further 1346 * exceptions thrown in this method are prevent the remainder of the 1347 * method from executing, but are otherwise ignored. 1348 * 1349 * @param thread the thread that has an uncaught exception 1350 * @param ex the exception that was thrown 1351 */ uncaughtException(Thread thread, Throwable ex)1352 void uncaughtException(Thread thread, Throwable ex); 1353 } 1354 1355 /** 1356 * Implementation of <code>unpark()</code>. See {@link LangAccessImpl}. 1357 */ unpark()1358 /*package*/ void unpark() { 1359 VMThread vmt = vmThread; 1360 1361 if (vmt == null) { 1362 /* 1363 * vmThread is null before the thread is start()ed. In 1364 * this case, we just go ahead and set the state to 1365 * PREEMPTIVELY_UNPARKED. Since this happens before the 1366 * thread is started, we don't have to worry about 1367 * synchronizing with it. 1368 */ 1369 parkState = ParkState.PREEMPTIVELY_UNPARKED; 1370 return; 1371 } 1372 1373 synchronized (vmt) { 1374 switch (parkState) { 1375 case ParkState.PREEMPTIVELY_UNPARKED: { 1376 /* 1377 * Nothing to do in this case: By definition, a 1378 * preemptively unparked thread is to remain in 1379 * the preemptively unparked state if it is told 1380 * to unpark. 1381 */ 1382 break; 1383 } 1384 case ParkState.UNPARKED: { 1385 parkState = ParkState.PREEMPTIVELY_UNPARKED; 1386 break; 1387 } 1388 default /*parked*/: { 1389 parkState = ParkState.UNPARKED; 1390 vmt.notifyAll(); 1391 break; 1392 } 1393 } 1394 } 1395 } 1396 1397 /** 1398 * Implementation of <code>parkFor()</code>. See {@link LangAccessImpl}. 1399 * This method must only be called when <code>this</code> is the current 1400 * thread. 1401 * 1402 * @param nanos number of nanoseconds to park for 1403 */ parkFor(long nanos)1404 /*package*/ void parkFor(long nanos) { 1405 VMThread vmt = vmThread; 1406 1407 if (vmt == null) { 1408 // Running threads should always have an associated vmThread. 1409 throw new AssertionError(); 1410 } 1411 1412 synchronized (vmt) { 1413 switch (parkState) { 1414 case ParkState.PREEMPTIVELY_UNPARKED: { 1415 parkState = ParkState.UNPARKED; 1416 break; 1417 } 1418 case ParkState.UNPARKED: { 1419 long millis = nanos / NANOS_PER_MILLI; 1420 nanos %= NANOS_PER_MILLI; 1421 1422 parkState = ParkState.PARKED; 1423 try { 1424 vmt.wait(millis, (int) nanos); 1425 } catch (InterruptedException ex) { 1426 interrupt(); 1427 } finally { 1428 /* 1429 * Note: If parkState manages to become 1430 * PREEMPTIVELY_UNPARKED before hitting this 1431 * code, it should left in that state. 1432 */ 1433 if (parkState == ParkState.PARKED) { 1434 parkState = ParkState.UNPARKED; 1435 } 1436 } 1437 break; 1438 } 1439 default /*parked*/: { 1440 throw new AssertionError( 1441 "shouldn't happen: attempt to repark"); 1442 } 1443 } 1444 } 1445 } 1446 1447 /** 1448 * Implementation of <code>parkUntil()</code>. See {@link LangAccessImpl}. 1449 * This method must only be called when <code>this</code> is the current 1450 * thread. 1451 * 1452 * @param time absolute milliseconds since the epoch to park until 1453 */ parkUntil(long time)1454 /*package*/ void parkUntil(long time) { 1455 VMThread vmt = vmThread; 1456 1457 if (vmt == null) { 1458 // Running threads should always have an associated vmThread. 1459 throw new AssertionError(); 1460 } 1461 1462 synchronized (vmt) { 1463 /* 1464 * Note: This conflates the two time bases of "wall clock" 1465 * time and "monotonic uptime" time. However, given that 1466 * the underlying system can only wait on monotonic time, 1467 * it is unclear if there is any way to avoid the 1468 * conflation. The downside here is that if, having 1469 * calculated the delay, the wall clock gets moved ahead, 1470 * this method may not return until well after the wall 1471 * clock has reached the originally designated time. The 1472 * reverse problem (the wall clock being turned back) 1473 * isn't a big deal, since this method is allowed to 1474 * spuriously return for any reason, and this situation 1475 * can safely be construed as just such a spurious return. 1476 */ 1477 long delayMillis = time - System.currentTimeMillis(); 1478 1479 if (delayMillis <= 0) { 1480 parkState = ParkState.UNPARKED; 1481 } else { 1482 parkFor(delayMillis * NANOS_PER_MILLI); 1483 } 1484 } 1485 } 1486 } 1487