java runnable类_java中多线程中Runnable接口和Thread类介绍

1 /*

2 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.4 *5 *6 *7 *8 *9 *10 *11 *12 *13 *14 *15 *16 *17 *18 *19 *20 *21 *22 *23 *24 */

25

26 packagejava.lang;27

28 importjava.lang.ref.Reference;29 importjava.lang.ref.ReferenceQueue;30 importjava.lang.ref.WeakReference;31 importjava.security.AccessController;32 importjava.security.AccessControlContext;33 importjava.security.PrivilegedAction;34 importjava.util.Map;35 importjava.util.HashMap;36 importjava.util.concurrent.ConcurrentHashMap;37 importjava.util.concurrent.ConcurrentMap;38 importjava.util.concurrent.locks.LockSupport;39 importsun.nio.ch.Interruptible;40 importsun.reflect.CallerSensitive;41 importsun.reflect.Reflection;42 importsun.security.util.SecurityConstants;43

44

45 /**

46 * A thread is a thread of execution in a program. The Java47 * Virtual Machine allows an application to have multiple threads of48 * execution running concurrently.49 *

50 * Every thread has a priority. Threads with higher priority are51 * executed in preference to threads with lower priority. Each thread52 * may or may not also be marked as a daemon. When code running in53 * some thread creates a new Thread object, the new54 * thread has its priority initially set equal to the priority of the55 * creating thread, and is a daemon thread if and only if the56 * creating thread is a daemon.57 *

58 * When a Java Virtual Machine starts up, there is usually a single59 * non-daemon thread (which typically calls the method named60 * main of some designated class). The Java Virtual61 * Machine continues to execute threads until either of the following62 * occurs:63 *

  • 64 *
  • The exit method of class Runtime has been65 * called and the security manager has permitted the exit operation66 * to take place.67 *
  • All threads that are not daemon threads have died, either by68 * returning from the call to the run method or by69 * throwing an exception that propagates beyond the run70 * method.71 *
72 *

73 * There are two ways to create a new thread of execution. One is to74 * declare a class to be a subclass of Thread. This75 * subclass should override the run method of class76 * Thread. An instance of the subclass can then be77 * allocated and started. For example, a thread that computes primes78 * larger than a stated value could be written as follows:79 *


80 *     class PrimeThread extends Thread {81 *         long minPrime;82 *         PrimeThread(long minPrime) {83 *             this.minPrime = minPrime;84 *         }85 *86 *         public void run() {87 *             // compute primes larger than minPrime88 *              . . .89 *         }90 *     }91 * 

92 *

93 * The following code would then create a thread and start it running:94 *

95 *     PrimeThread p = new PrimeThread(143);96 *     p.start();97 * 
98 *

99 * The other way to create a thread is to declare a class that100 * implements the Runnable interface. That class then101 * implements the run method. An instance of the class can102 * then be allocated, passed as an argument when creating103 * Thread, and started. The same example in this other104 * style looks like the following:105 *


106 *     class PrimeRun implements Runnable {107 *         long minPrime;108 *         PrimeRun(long minPrime) {109 *             this.minPrime = minPrime;110 *         }111 *112 *         public void run() {113 *             // compute primes larger than minPrime114 *              . . .115 *         }116 *     }117 * 

118 *

119 * The following code would then create a thread and start it running:120 *

121 *     PrimeRun p = new PrimeRun(143);122 *     new Thread(p).start();123 * 
124 *

125 * Every thread has a name for identification purposes. More than126 * one thread may have the same name. If a name is not specified when127 * a thread is created, a new name is generated for it.128 *

129 * Unless otherwise noted, passing a {@codenull} argument to a constructor130 * or method in this class will cause a {@linkNullPointerException} to be131 * thrown.132 *133 *@authorunascribed134 *@seeRunnable135 *@seeRuntime#exit(int)136 *@see#run()137 *@see#stop()138 *@sinceJDK1.0139 */

140 public

141 class Thread implementsRunnable {142 /*Make sure registerNatives is the first thing does.*/

143 private static native voidregisterNatives();144 static{145 registerNatives();146 }147

148 private volatile charname[];149 private intpriority;150 privateThread threadQ;151 private longeetop;152

153 /*Whether or not to single_step this thread.*/

154 private booleansingle_step;155

156 /*Whether or not the thread is a daemon thread.*/

157 private boolean daemon = false;158

159 /*JVM state*/

160 private boolean stillborn = false;161

162 /*What will be run.*/

163 privateRunnable target;164

165 /*The group of this thread*/

166 privateThreadGroup group;167

168 /*The context ClassLoader for this thread*/

169 privateClassLoader contextClassLoader;170

171 /*The inherited AccessControlContext of this thread*/

172 privateAccessControlContext inheritedAccessControlContext;173

174 /*For autonumbering anonymous threads.*/

175 private static intthreadInitNumber;176 private static synchronized intnextThreadNum() {177 return threadInitNumber++;178 }179

180 /*ThreadLocal values pertaining to this thread. This map is maintained181 * by the ThreadLocal class.*/

182 ThreadLocal.ThreadLocalMap threadLocals = null;183

184 /*

185 * InheritableThreadLocal values pertaining to this thread. This map is186 * maintained by the InheritableThreadLocal class.187 */

188 ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;189

190 /*

191 * The requested stack size for this thread, or 0 if the creator did192 * not specify a stack size. It is up to the VM to do whatever it193 * likes with this number; some VMs will ignore it.194 */

195 private longstackSize;196

197 /*

198 * JVM-private state that persists after native thread termination.199 */

200 private longnativeParkEventPointer;201

202 /*

203 * Thread ID204 */

205 private longtid;206

207 /*For generating thread ID*/

208 private static longthreadSeqNumber;209

210 /*Java thread status for tools,211 * initialized to indicate thread 'not yet started'212 */

213

214 private volatile int threadStatus = 0;215

216

217 private static synchronized longnextThreadID() {218 return ++threadSeqNumber;219 }220

221 /**

222 * The argument supplied to the current call to223 * java.util.concurrent.locks.LockSupport.park.224 * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker225 * Accessed using java.util.concurrent.locks.LockSupport.getBlocker226 */

227 volatileObject parkBlocker;228

229 /*The object in which this thread is blocked in an interruptible I/O230 * operation, if any. The blocker's interrupt method should be invoked231 * after setting this thread's interrupt status.232 */

233 private volatileInterruptible blocker;234 private final Object blockerLock = newObject();235

236 /*Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code237 */

238 voidblockedOn(Interruptible b) {239 synchronized(blockerLock) {240 blocker =b;241 }242 }243

244 /**

245 * The minimum priority that a thread can have.246 */

247 public final static int MIN_PRIORITY = 1;248

249 /**

250 * The default priority that is assigned to a thread.251 */

252 public final static int NORM_PRIORITY = 5;253

254 /**

255 * The maximum priority that a thread can have.256 */

257 public final static int MAX_PRIORITY = 10;258

259 /**

260 * Returns a reference to the currently executing thread object.261 *262 *@returnthe currently executing thread.263 */

264 public static nativeThread currentThread();265

266 /**

267 * A hint to the scheduler that the current thread is willing to yield268 * its current use of a processor. The scheduler is free to ignore this269 * hint.270 *271 *

Yield is a heuristic attempt to improve relative progression272 * between threads that would otherwise over-utilise a CPU. Its use273 * should be combined with detailed profiling and benchmarking to274 * ensure that it actually has the desired effect.275 *276 *

It is rarely appropriate to use this method. It may be useful277 * for debugging or testing purposes, where it may help to reproduce278 * bugs due to race conditions. It may also be useful when designing279 * concurrency control constructs such as the ones in the280 * {@linkjava.util.concurrent.locks} package.281 */

282 public static native voidyield();283

284 /**

285 * Causes the currently executing thread to sleep (temporarily cease286 * execution) for the specified number of milliseconds, subject to287 * the precision and accuracy of system timers and schedulers. The thread288 * does not lose ownership of any monitors.289 *290 *@parammillis291 * the length of time to sleep in milliseconds292 *293 *@throwsIllegalArgumentException294 * if the value of {@codemillis} is negative295 *296 *@throwsInterruptedException297 * if any thread has interrupted the current thread. The298 * interrupted status of the current thread is299 * cleared when this exception is thrown.300 */

301 public static native void sleep(long millis) throwsInterruptedException;302

303 /**

304 * Causes the currently executing thread to sleep (temporarily cease305 * execution) for the specified number of milliseconds plus the specified306 * number of nanoseconds, subject to the precision and accuracy of system307 * timers and schedulers. The thread does not lose ownership of any308 * monitors.309 *310 *@parammillis311 * the length of time to sleep in milliseconds312 *313 *@paramnanos314 * {@code0-999999} additional nanoseconds to sleep315 *316 *@throwsIllegalArgumentException317 * if the value of {@codemillis} is negative, or the value of318 * {@codenanos} is not in the range {@code0-999999}319 *320 *@throwsInterruptedException321 * if any thread has interrupted the current thread. The322 * interrupted status of the current thread is323 * cleared when this exception is thrown.324 */

325 public static void sleep(long millis, intnanos)326 throwsInterruptedException {327 if (millis < 0) {328 throw new IllegalArgumentException("timeout value is negative");329 }330

331 if (nanos < 0 || nanos > 999999) {332 throw newIllegalArgumentException(333 "nanosecond timeout value out of range");334 }335

336 if (nanos >= 500000 || (nanos != 0 && millis == 0)) {337 millis++;338 }339

340 sleep(millis);341 }342

343 /**

344 * Initializes a Thread with the current AccessControlContext.345 *@see#init(ThreadGroup,Runnable,String,long,AccessControlContext)346 */

347 private voidinit(ThreadGroup g, Runnable target, String name,348 longstackSize) {349 init(g, target, name, stackSize, null);350 }351

352 /**

353 * Initializes a Thread.354 *355 *@paramg the Thread group356 *@paramtarget the object whose run() method gets called357 *@paramname the name of the new Thread358 *@paramstackSize the desired stack size for the new thread, or359 * zero to indicate that this parameter is to be ignored.360 *@paramacc the AccessControlContext to inherit, or361 * AccessController.getContext() if null362 */

363 private voidinit(ThreadGroup g, Runnable target, String name,364 longstackSize, AccessControlContext acc) {365 if (name == null) {366 throw new NullPointerException("name cannot be null");367 }368

369 this.name =name.toCharArray();370

371 Thread parent =currentThread();372 SecurityManager security =System.getSecurityManager();373 if (g == null) {374 /*Determine if it's an applet or not*/

375

376 /*If there is a security manager, ask the security manager377 what to do.*/

378 if (security != null) {379 g =security.getThreadGroup();380 }381

382 /*If the security doesn't have a strong opinion of the matter383 use the parent thread group.*/

384 if (g == null) {385 g =parent.getThreadGroup();386 }387 }388

389 /*checkAccess regardless of whether or not threadgroup is390 explicitly passed in.*/

391 g.checkAccess();392

393 /*

394 * Do we have the required permissions?395 */

396 if (security != null) {397 if(isCCLOverridden(getClass())) {398 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);399 }400 }401

402 g.addUnstarted();403

404 this.group =g;405 this.daemon =parent.isDaemon();406 this.priority =parent.getPriority();407 if (security == null ||isCCLOverridden(parent.getClass()))408 this.contextClassLoader =parent.getContextClassLoader();409 else

410 this.contextClassLoader =parent.contextClassLoader;411 this.inheritedAccessControlContext =

412 acc != null ?acc : AccessController.getContext();413 this.target =target;414 setPriority(priority);415 if (parent.inheritableThreadLocals != null)416 this.inheritableThreadLocals =

417 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);418 /*Stash the specified stack size in case the VM cares*/

419 this.stackSize =stackSize;420

421 /*Set thread ID*/

422 tid =nextThreadID();423 }424

425 /**

426 * Throws CloneNotSupportedException as a Thread can not be meaningfully427 * cloned. Construct a new Thread instead.428 *429 *@throwsCloneNotSupportedException430 * always431 */

432 @Override433 protected Object clone() throwsCloneNotSupportedException {434 throw newCloneNotSupportedException();435 }436

437 /**

438 * Allocates a new {@codeThread} object. This constructor has the same439 * effect as {@linkplain#Thread(ThreadGroup,Runnable,String) Thread}440 * {@code(null, null, gname)}, where {@codegname} is a newly generated441 * name. Automatically generated names are of the form442 * {@code"Thread-"+}n, where n is an integer.443 */

444 publicThread() {445 init(null, null, "Thread-" + nextThreadNum(), 0);446 }447

448 /**

449 * Allocates a new {@codeThread} object. This constructor has the same450 * effect as {@linkplain#Thread(ThreadGroup,Runnable,String) Thread}451 * {@code(null, target, gname)}, where {@codegname} is a newly generated452 * name. Automatically generated names are of the form453 * {@code"Thread-"+}n, where n is an integer.454 *455 *@paramtarget456 * the object whose {@coderun} method is invoked when this thread457 * is started. If {@codenull}, this classes {@coderun} method does458 * nothing.459 */

460 publicThread(Runnable target) {461 init(null, target, "Thread-" + nextThreadNum(), 0);462 }463

464 /**

465 * Creates a new Thread that inherits the given AccessControlContext.466 * This is not a public constructor.467 */

468 Thread(Runnable target, AccessControlContext acc) {469 init(null, target, "Thread-" + nextThreadNum(), 0, acc);470 }471

472 /**

473 * Allocates a new {@codeThread} object. This constructor has the same474 * effect as {@linkplain#Thread(ThreadGroup,Runnable,String) Thread}475 * {@code(group, target, gname)} ,where {@codegname} is a newly generated476 * name. Automatically generated names are of the form477 * {@code"Thread-"+}n, where n is an integer.478 *479 *@paramgroup480 * the thread group. If {@codenull} and there is a security481 * manager, the group is determined by {@linkplain

482 * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.483 * If there is not a security manager or {@code

484 * SecurityManager.getThreadGroup()} returns {@codenull}, the group485 * is set to the current thread's thread group.486 *487 *@paramtarget488 * the object whose {@coderun} method is invoked when this thread489 * is started. If {@codenull}, this thread's run method is invoked.490 *491 *@throwsSecurityException492 * if the current thread cannot create a thread in the specified493 * thread group494 */

495 publicThread(ThreadGroup group, Runnable target) {496 init(group, target, "Thread-" + nextThreadNum(), 0);497 }498

499 /**

500 * Allocates a new {@codeThread} object. This constructor has the same501 * effect as {@linkplain#Thread(ThreadGroup,Runnable,String) Thread}502 * {@code(null, null, name)}.503 *504 *@paramname505 * the name of the new thread506 */

507 publicThread(String name) {508 init(null, null, name, 0);509 }510

511 /**

512 * Allocates a new {@codeThread} object. This constructor has the same513 * effect as {@linkplain#Thread(ThreadGroup,Runnable,String) Thread}514 * {@code(group, null, name)}.515 *516 *@paramgroup517 * the thread group. If {@codenull} and there is a security518 * manager, the group is determined by {@linkplain

519 * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.520 * If there is not a security manager or {@code

521 * SecurityManager.getThreadGroup()} returns {@codenull}, the group522 * is set to the current thread's thread group.523 *524 *@paramname525 * the name of the new thread526 *527 *@throwsSecurityException528 * if the current thread cannot create a thread in the specified529 * thread group530 */

531 publicThread(ThreadGroup group, String name) {532 init(group, null, name, 0);533 }534

535 /**

536 * Allocates a new {@codeThread} object. This constructor has the same537 * effect as {@linkplain#Thread(ThreadGroup,Runnable,String) Thread}538 * {@code(null, target, name)}.539 *540 *@paramtarget541 * the object whose {@coderun} method is invoked when this thread542 * is started. If {@codenull}, this thread's run method is invoked.543 *544 *@paramname545 * the name of the new thread546 */

547 publicThread(Runnable target, String name) {548 init(null, target, name, 0);549 }550

551 /**

552 * Allocates a new {@codeThread} object so that it has {@codetarget}553 * as its run object, has the specified {@codename} as its name,554 * and belongs to the thread group referred to by {@codegroup}.555 *556 *

If there is a security manager, its557 * {@linkSecurityManager#checkAccess(ThreadGroup) checkAccess}558 * method is invoked with the ThreadGroup as its argument.559 *560 *

In addition, its {@codecheckPermission} method is invoked with561 * the {@codeRuntimePermission("enableContextClassLoaderOverride")}562 * permission when invoked directly or indirectly by the constructor563 * of a subclass which overrides the {@codegetContextClassLoader}564 * or {@codesetContextClassLoader} methods.565 *566 *

The priority of the newly created thread is set equal to the567 * priority of the thread creating it, that is, the currently running568 * thread. The method {@linkplain#setPriority setPriority} may be569 * used to change the priority to a new value.570 *571 *

The newly created thread is initially marked as being a daemon572 * thread if and only if the thread creating it is currently marked573 * as a daemon thread. The method {@linkplain#setDaemon setDaemon}574 * may be used to change whether or not a thread is a daemon.575 *576 *@paramgroup577 * the thread group. If {@codenull} and there is a security578 * manager, the group is determined by {@linkplain

579 * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.580 * If there is not a security manager or {@code

581 * SecurityManager.getThreadGroup()} returns {@codenull}, the group582 * is set to the current thread's thread group.583 *584 *@paramtarget585 * the object whose {@coderun} method is invoked when this thread586 * is started. If {@codenull}, this thread's run method is invoked.587 *588 *@paramname589 * the name of the new thread590 *591 *@throwsSecurityException592 * if the current thread cannot create a thread in the specified593 * thread group or cannot override the context class loader methods.594 */

595 publicThread(ThreadGroup group, Runnable target, String name) {596 init(group, target, name, 0);597 }598

599 /**

600 * Allocates a new {@codeThread} object so that it has {@codetarget}601 * as its run object, has the specified {@codename} as its name,602 * and belongs to the thread group referred to by {@codegroup}, and has603 * the specified stack size.604 *605 *

This constructor is identical to {@link

606 * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact607 * that it allows the thread stack size to be specified. The stack size608 * is the approximate number of bytes of address space that the virtual609 * machine is to allocate for this thread's stack. The effect of the610 * {@codestackSize} parameter, if any, is highly platform dependent.611 *612 *

On some platforms, specifying a higher value for the613 * {@codestackSize} parameter may allow a thread to achieve greater614 * recursion depth before throwing a {@linkStackOverflowError}.615 * Similarly, specifying a lower value may allow a greater number of616 * threads to exist concurrently without throwing an {@link

617 * OutOfMemoryError} (or other internal error). The details of618 * the relationship between the value of the stackSize parameter619 * and the maximum recursion depth and concurrency level are620 * platform-dependent. On some platforms, the value of the621 * {@codestackSize} parameter may have no effect whatsoever.622 *623 *

The virtual machine is free to treat the {@codestackSize}624 * parameter as a suggestion. If the specified value is unreasonably low625 * for the platform, the virtual machine may instead use some626 * platform-specific minimum value; if the specified value is unreasonably627 * high, the virtual machine may instead use some platform-specific628 * maximum. Likewise, the virtual machine is free to round the specified629 * value up or down as it sees fit (or to ignore it completely).630 *631 *

Specifying a value of zero for the {@codestackSize} parameter will632 * cause this constructor to behave exactly like the633 * {@codeThread(ThreadGroup, Runnable, String)} constructor.634 *635 *

Due to the platform-dependent nature of the behavior of this636 * constructor, extreme care should be exercised in its use.637 * The thread stack size necessary to perform a given computation will638 * likely vary from one JRE implementation to another. In light of this639 * variation, careful tuning of the stack size parameter may be required,640 * and the tuning may need to be repeated for each JRE implementation on641 * which an application is to run.642 *643 *

Implementation note: Java platform implementers are encouraged to644 * document their implementation's behavior with respect to the645 * {@codestackSize} parameter.646 *647 *648 *@paramgroup649 * the thread group. If {@codenull} and there is a security650 * manager, the group is determined by {@linkplain

651 * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.652 * If there is not a security manager or {@code

653 * SecurityManager.getThreadGroup()} returns {@codenull}, the group654 * is set to the current thread's thread group.655 *656 *@paramtarget657 * the object whose {@coderun} method is invoked when this thread658 * is started. If {@codenull}, this thread's run method is invoked.659 *660 *@paramname661 * the name of the new thread662 *663 *@paramstackSize664 * the desired stack size for the new thread, or zero to indicate665 * that this parameter is to be ignored.666 *667 *@throwsSecurityException668 * if the current thread cannot create a thread in the specified669 * thread group670 *671 *@since1.4672 */

673 publicThread(ThreadGroup group, Runnable target, String name,674 longstackSize) {675 init(group, target, name, stackSize);676 }677

678 /**

679 * Causes this thread to begin execution; the Java Virtual Machine680 * calls the run method of this thread.681 *

682 * The result is that two threads are running concurrently: the683 * current thread (which returns from the call to the684 * start method) and the other thread (which executes its685 * run method).686 *

687 * It is never legal to start a thread more than once.688 * In particular, a thread may not be restarted once it has completed689 * execution.690 *691 *@exceptionIllegalThreadStateException if the thread was already692 * started.693 *@see#run()694 *@see#stop()695 */

696 public synchronized voidstart() {697 /**

698 * This method is not invoked for the main method thread or "system"699 * group threads created/set up by the VM. Any new functionality added700 * to this method in the future may have to also be added to the VM.701 *702 * A zero status value corresponds to state "NEW".703 */

704 if (threadStatus != 0)705 throw newIllegalThreadStateException();706

707 /*Notify the group that this thread is about to be started708 * so that it can be added to the group's list of threads709 * and the group's unstarted count can be decremented.*/

710 group.add(this);711

712 boolean started = false;713 try{714 start0();715 started = true;716 } finally{717 try{718 if (!started) {719 group.threadStartFailed(this);720 }721 } catch(Throwable ignore) {722 /*do nothing. If start0 threw a Throwable then723 it will be passed up the call stack*/

724 }725 }726 }727

728 private native voidstart0();729

730 /**

731 * If this thread was constructed using a separate732 * Runnable run object, then that733 * Runnable object's run method is called;734 * otherwise, this method does nothing and returns.735 *

736 * Subclasses of Thread should override this method.737 *738 *@see#start()739 *@see#stop()740 *@see#Thread(ThreadGroup, Runnable, String)741 */

742 @Override743 public voidrun() {744 if (target != null) {745 target.run();746 }747 }748

749 /**

750 * This method is called by the system to give a Thread751 * a chance to clean up before it actually exits.752 */

753 private voidexit() {754 if (group != null) {755 group.threadTerminated(this);756 group = null;757 }758 /*Aggressively null out all reference fields: see bug 4006245*/

759 target = null;760 /*Speed the release of some of these resources*/

761 threadLocals = null;762 inheritableThreadLocals = null;763 inheritedAccessControlContext = null;764 blocker = null;765 uncaughtExceptionHandler = null;766 }767

768 /**

769 * Forces the thread to stop executing.770 *

771 * If there is a security manager installed, its checkAccess772 * method is called with this773 * as its argument. This may result in a774 * SecurityException being raised (in the current thread).775 *

776 * If this thread is different from the current thread (that is, the current777 * thread is trying to stop a thread other than itself), the778 * security manager's checkPermission method (with a779 * RuntimePermission("stopThread") argument) is called in780 * addition.781 * Again, this may result in throwing a782 * SecurityException (in the current thread).783 *

784 * The thread represented by this thread is forced to stop whatever785 * it is doing abnormally and to throw a newly created786 * ThreadDeath object as an exception.787 *

788 * It is permitted to stop a thread that has not yet been started.789 * If the thread is eventually started, it immediately terminates.790 *

791 * An application should not normally try to catch792 * ThreadDeath unless it must do some extraordinary793 * cleanup operation (note that the throwing of794 * ThreadDeath causes finally clauses of795 * try statements to be executed before the thread796 * officially dies). If a catch clause catches a797 * ThreadDeath object, it is important to rethrow the798 * object so that the thread actually dies.799 *

800 * The top-level error handler that reacts to otherwise uncaught801 * exceptions does not print out a message or otherwise notify the802 * application if the uncaught exception is an instance of803 * ThreadDeath.804 *805 *@exceptionSecurityException if the current thread cannot806 * modify this thread.807 *@see#interrupt()808 *@see#checkAccess()809 *@see#run()810 *@see#start()811 *@seeThreadDeath812 *@seeThreadGroup#uncaughtException(Thread,Throwable)813 *@seeSecurityManager#checkAccess(Thread)814 *@seeSecurityManager#checkPermission815 *@deprecatedThis method is inherently unsafe. Stopping a thread with816 * Thread.stop causes it to unlock all of the monitors that it817 * has locked (as a natural consequence of the unchecked818 * ThreadDeath exception propagating up the stack). If819 * any of the objects previously protected by these monitors were in820 * an inconsistent state, the damaged objects become visible to821 * other threads, potentially resulting in arbitrary behavior. Many822 * uses of stop should be replaced by code that simply823 * modifies some variable to indicate that the target thread should824 * stop running. The target thread should check this variable825 * regularly, and return from its run method in an orderly fashion826 * if the variable indicates that it is to stop running. If the827 * target thread waits for long periods (on a condition variable,828 * for example), the interrupt method should be used to829 * interrupt the wait.830 * For more information, see831 * Why832 * are Thread.stop, Thread.suspend and Thread.resume Deprecated?.833 */

834 @Deprecated835 public final voidstop() {836 SecurityManager security =System.getSecurityManager();837 if (security != null) {838 checkAccess();839 if (this !=Thread.currentThread()) {840 security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);841 }842 }843 //A zero status value corresponds to "NEW", it can't change to844 //not-NEW because we hold the lock.

845 if (threadStatus != 0) {846 resume(); //Wake up thread if it was suspended; no-op otherwise

847 }848

849 //The VM can handle all thread states

850 stop0(newThreadDeath());851 }852

853 /**

854 * Throws {@codeUnsupportedOperationException}.855 *856 *@paramobj ignored857 *858 *@deprecatedThis method was originally designed to force a thread to stop859 * and throw a given {@codeThrowable} as an exception. It was860 * inherently unsafe (see {@link#stop()} for details), and furthermore861 * could be used to generate exceptions that the target thread was862 * not prepared to handle.863 * For more information, see864 * Why865 * are Thread.stop, Thread.suspend and Thread.resume Deprecated?.866 */

867 @Deprecated868 public final synchronized voidstop(Throwable obj) {869 throw newUnsupportedOperationException();870 }871

872 /**

873 * Interrupts this thread.874 *875 *

Unless the current thread is interrupting itself, which is876 * always permitted, the {@link#checkAccess() checkAccess} method877 * of this thread is invoked, which may cause a {@link

878 * SecurityException} to be thrown.879 *880 *

If this thread is blocked in an invocation of the {@link

881 * Object#wait() wait()}, {@linkObject#wait(long) wait(long)}, or {@link

882 * Object#wait(long, int) wait(long, int)} methods of the {@linkObject}883 * class, or of the {@link#join()}, {@link#join(long)}, {@link

884 * #join(long, int)}, {@link#sleep(long)}, or {@link#sleep(long, int)},885 * methods of this class, then its interrupt status will be cleared and it886 * will receive an {@linkInterruptedException}.887 *888 *

If this thread is blocked in an I/O operation upon an {@link

889 * java.nio.channels.InterruptibleChannel InterruptibleChannel}890 * then the channel will be closed, the thread's interrupt891 * status will be set, and the thread will receive a {@link

892 * java.nio.channels.ClosedByInterruptException}.893 *894 *

If this thread is blocked in a {@linkjava.nio.channels.Selector}895 * then the thread's interrupt status will be set and it will return896 * immediately from the selection operation, possibly with a non-zero897 * value, just as if the selector's {@link

898 * java.nio.channels.Selector#wakeup wakeup} method were invoked.899 *900 *

If none of the previous conditions hold then this thread's interrupt901 * status will be set.

902 *903 *

Interrupting a thread that is not alive need not have any effect.904 *905 *@throwsSecurityException906 * if the current thread cannot modify this thread907 *908 * @revised 6.0909 * @spec JSR-51910 */

911 public voidinterrupt() {912 if (this !=Thread.currentThread())913 checkAccess();914

915 synchronized(blockerLock) {916 Interruptible b =blocker;917 if (b != null) {918 interrupt0(); //Just to set the interrupt flag

919 b.interrupt(this);920 return;921 }922 }923 interrupt0();924 }925

926 /**

927 * Tests whether the current thread has been interrupted. The928 * interrupted status of the thread is cleared by this method. In929 * other words, if this method were to be called twice in succession, the930 * second call would return false (unless the current thread were931 * interrupted again, after the first call had cleared its interrupted932 * status and before the second call had examined it).933 *934 *

A thread interruption ignored because a thread was not alive935 * at the time of the interrupt will be reflected by this method936 * returning false.937 *938 *@returntrue if the current thread has been interrupted;939 * false otherwise.940 *@see#isInterrupted()941 * @revised 6.0942 */

943 public static booleaninterrupted() {944 return currentThread().isInterrupted(true);945 }946

947 /**

948 * Tests whether this thread has been interrupted. The interrupted949 * status of the thread is unaffected by this method.950 *951 *

A thread interruption ignored because a thread was not alive952 * at the time of the interrupt will be reflected by this method953 * returning false.954 *955 *@returntrue if this thread has been interrupted;956 * false otherwise.957 *@see#interrupted()958 * @revised 6.0959 */

960 public booleanisInterrupted() {961 return isInterrupted(false);962 }963

964 /**

965 * Tests if some Thread has been interrupted. The interrupted state966 * is reset or not based on the value of ClearInterrupted that is967 * passed.968 */

969 private native boolean isInterrupted(booleanClearInterrupted);970

971 /**

972 * Throws {@linkNoSuchMethodError}.973 *974 *@deprecatedThis method was originally designed to destroy this975 * thread without any cleanup. Any monitors it held would have976 * remained locked. However, the method was never implemented.977 * If if were to be implemented, it would be deadlock-prone in978 * much the manner of {@link#suspend}. If the target thread held979 * a lock protecting a critical system resource when it was980 * destroyed, no thread could ever access this resource again.981 * If another thread ever attempted to lock this resource, deadlock982 * would result. Such deadlocks typically manifest themselves as983 * "frozen" processes. For more information, see984 * 985 * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.986 *@throwsNoSuchMethodError always987 */

988 @Deprecated989 public voiddestroy() {990 throw newNoSuchMethodError();991 }992

993 /**

994 * Tests if this thread is alive. A thread is alive if it has995 * been started and has not yet died.996 *997 *@returntrue if this thread is alive;998 * false otherwise.999 */

1000 public final native booleanisAlive();1001

1002 /**

1003 * Suspends this thread.1004 *

1005 * First, the checkAccess method of this thread is called1006 * with no arguments. This may result in throwing a1007 * SecurityException (in the current thread).1008 *

1009 * If the thread is alive, it is suspended and makes no further1010 * progress unless and until it is resumed.1011 *1012 *@exceptionSecurityException if the current thread cannot modify1013 * this thread.1014 *@see#checkAccess1015 *@deprecatedThis method has been deprecated, as it is1016 * inherently deadlock-prone. If the target thread holds a lock on the1017 * monitor protecting a critical system resource when it is suspended, no1018 * thread can access this resource until the target thread is resumed. If1019 * the thread that would resume the target thread attempts to lock this1020 * monitor prior to calling resume, deadlock results. Such1021 * deadlocks typically manifest themselves as "frozen" processes.1022 * For more information, see1023 * Why1024 * are Thread.stop, Thread.suspend and Thread.resume Deprecated?.1025 */

1026 @Deprecated1027 public final voidsuspend() {1028 checkAccess();1029 suspend0();1030 }1031

1032 /**

1033 * Resumes a suspended thread.1034 *

1035 * First, the checkAccess method of this thread is called1036 * with no arguments. This may result in throwing a1037 * SecurityException (in the current thread).1038 *

1039 * If the thread is alive but suspended, it is resumed and is1040 * permitted to make progress in its execution.1041 *1042 *@exceptionSecurityException if the current thread cannot modify this1043 * thread.1044 *@see#checkAccess1045 *@see#suspend()1046 *@deprecatedThis method exists solely for use with {@link#suspend},1047 * which has been deprecated because it is deadlock-prone.1048 * For more information, see1049 * Why1050 * are Thread.stop, Thread.suspend and Thread.resume Deprecated?.1051 */

1052 @Deprecated1053 public final voidresume() {1054 checkAccess();1055 resume0();1056 }1057

1058 /**

1059 * Changes the priority of this thread.1060 *

1061 * First the checkAccess method of this thread is called1062 * with no arguments. This may result in throwing a1063 * SecurityException.1064 *

1065 * Otherwise, the priority of this thread is set to the smaller of1066 * the specified newPriority and the maximum permitted1067 * priority of the thread's thread group.1068 *1069 *@paramnewPriority priority to set this thread to1070 *@exceptionIllegalArgumentException If the priority is not in the1071 * range MIN_PRIORITY to1072 * MAX_PRIORITY.1073 *@exceptionSecurityException if the current thread cannot modify1074 * this thread.1075 *@see#getPriority1076 *@see#checkAccess()1077 *@see#getThreadGroup()1078 *@see#MAX_PRIORITY1079 *@see#MIN_PRIORITY1080 *@seeThreadGroup#getMaxPriority()1081 */

1082 public final void setPriority(intnewPriority) {1083 ThreadGroup g;1084 checkAccess();1085 if (newPriority > MAX_PRIORITY || newPriority g.getMaxPriority()) {1090 newPriority =g.getMaxPriority();1091 }1092 setPriority0(priority =newPriority);1093 }1094 }1095

1096 /**

1097 * Returns this thread's priority.1098 *1099 *@returnthis thread's priority.1100 *@see#setPriority1101 */

1102 public final intgetPriority() {1103 returnpriority;1104 }1105

1106 /**

1107 * Changes the name of this thread to be equal to the argument1108 * name.1109 *

1110 * First the checkAccess method of this thread is called1111 * with no arguments. This may result in throwing a1112 * SecurityException.1113 *1114 *@paramname the new name for this thread.1115 *@exceptionSecurityException if the current thread cannot modify this1116 * thread.1117 *@see#getName1118 *@see#checkAccess()1119 */

1120 public final synchronized voidsetName(String name) {1121 checkAccess();1122 this.name =name.toCharArray();1123 if (threadStatus != 0) {1124 setNativeName(name);1125 }1126 }1127

1128 /**

1129 * Returns this thread's name.1130 *1131 *@returnthis thread's name.1132 *@see#setName(String)1133 */

1134 public finalString getName() {1135 return new String(name, true);1136 }1137

1138 /**

1139 * Returns the thread group to which this thread belongs.1140 * This method returns null if this thread has died1141 * (been stopped).1142 *1143 *@returnthis thread's thread group.1144 */

1145 public finalThreadGroup getThreadGroup() {1146 returngroup;1147 }1148

1149 /**

1150 * Returns an estimate of the number of active threads in the current1151 * thread's {@linkplainjava.lang.ThreadGroup thread group} and its1152 * subgroups. Recursively iterates over all subgroups in the current1153 * thread's thread group.1154 *1155 *

The value returned is only an estimate because the number of1156 * threads may change dynamically while this method traverses internal1157 * data structures, and might be affected by the presence of certain1158 * system threads. This method is intended primarily for debugging1159 * and monitoring purposes.1160 *1161 *@returnan estimate of the number of active threads in the current1162 * thread's thread group and in any other thread group that1163 * has the current thread's thread group as an ancestor1164 */

1165 public static intactiveCount() {1166 returncurrentThread().getThreadGroup().activeCount();1167 }1168

1169 /**

1170 * Copies into the specified array every active thread in the current1171 * thread's thread group and its subgroups. This method simply1172 * invokes the {@linkjava.lang.ThreadGroup#enumerate(Thread[])}1173 * method of the current thread's thread group.1174 *1175 *

An application might use the {@linkplain#activeCount activeCount}1176 * method to get an estimate of how big the array should be, however1177 * if the array is too short to hold all the threads, the extra threads1178 * are silently ignored. If it is critical to obtain every active1179 * thread in the current thread's thread group and its subgroups, the1180 * invoker should verify that the returned int value is strictly less1181 * than the length of {@codetarray}.1182 *1183 *

Due to the inherent race condition in this method, it is recommended1184 * that the method only be used for debugging and monitoring purposes.1185 *1186 *@paramtarray1187 * an array into which to put the list of threads1188 *1189 *@returnthe number of threads put into the array1190 *1191 *@throwsSecurityException1192 * if {@linkjava.lang.ThreadGroup#checkAccess} determines that1193 * the current thread cannot access its thread group1194 */

1195 public static intenumerate(Thread tarray[]) {1196 returncurrentThread().getThreadGroup().enumerate(tarray);1197 }1198

1199 /**

1200 * Counts the number of stack frames in this thread. The thread must1201 * be suspended.1202 *1203 *@returnthe number of stack frames in this thread.1204 *@exceptionIllegalThreadStateException if this thread is not1205 * suspended.1206 *@deprecatedThe definition of this call depends on {@link#suspend},1207 * which is deprecated. Further, the results of this call1208 * were never well-defined.1209 */

1210 @Deprecated1211 public native intcountStackFrames();1212

1213 /**

1214 * Waits at most {@codemillis} milliseconds for this thread to1215 * die. A timeout of {@code0} means to wait forever.1216 *1217 *

This implementation uses a loop of {@codethis.wait} calls1218 * conditioned on {@codethis.isAlive}. As a thread terminates the1219 * {@codethis.notifyAll} method is invoked. It is recommended that1220 * applications not use {@codewait}, {@codenotify}, or1221 * {@codenotifyAll} on {@codeThread} instances.1222 *1223 *@parammillis1224 * the time to wait in milliseconds1225 *1226 *@throwsIllegalArgumentException1227 * if the value of {@codemillis} is negative1228 *1229 *@throwsInterruptedException1230 * if any thread has interrupted the current thread. The1231 * interrupted status of the current thread is1232 * cleared when this exception is thrown.1233 */

1234 public final synchronized void join(longmillis)1235 throwsInterruptedException {1236 long base =System.currentTimeMillis();1237 long now = 0;1238

1239 if (millis < 0) {1240 throw new IllegalArgumentException("timeout value is negative");1241 }1242

1243 if (millis == 0) {1244 while(isAlive()) {1245 wait(0);1246 }1247 } else{1248 while(isAlive()) {1249 long delay = millis -now;1250 if (delay <= 0) {1251 break;1252 }1253 wait(delay);1254 now = System.currentTimeMillis() -base;1255 }1256 }1257 }1258

1259 /**

1260 * Waits at most {@codemillis} milliseconds plus1261 * {@codenanos} nanoseconds for this thread to die.1262 *1263 *

This implementation uses a loop of {@codethis.wait} calls1264 * conditioned on {@codethis.isAlive}. As a thread terminates the1265 * {@codethis.notifyAll} method is invoked. It is recommended that1266 * applications not use {@codewait}, {@codenotify}, or1267 * {@codenotifyAll} on {@codeThread} instances.1268 *1269 *@parammillis1270 * the time to wait in milliseconds1271 *1272 *@paramnanos1273 * {@code0-999999} additional nanoseconds to wait1274 *1275 *@throwsIllegalArgumentException1276 * if the value of {@codemillis} is negative, or the value1277 * of {@codenanos} is not in the range {@code0-999999}1278 *1279 *@throwsInterruptedException1280 * if any thread has interrupted the current thread. The1281 * interrupted status of the current thread is1282 * cleared when this exception is thrown.1283 */

1284 public final synchronized void join(long millis, intnanos)1285 throwsInterruptedException {1286

1287 if (millis < 0) {1288 throw new IllegalArgumentException("timeout value is negative");1289 }1290

1291 if (nanos < 0 || nanos > 999999) {1292 throw newIllegalArgumentException(1293 "nanosecond timeout value out of range");1294 }1295

1296 if (nanos >= 500000 || (nanos != 0 && millis == 0)) {1297 millis++;1298 }1299

1300 join(millis);1301 }1302

1303 /**

1304 * Waits for this thread to die.1305 *1306 *

An invocation of this method behaves in exactly the same1307 * way as the invocation1308 *1309 *

1310 * {@linkplain#join(long) join}{@code(0)}1311 *
1312 *1313 *@throwsInterruptedException1314 * if any thread has interrupted the current thread. The1315 * interrupted status of the current thread is1316 * cleared when this exception is thrown.1317 */

1318 public final void join() throwsInterruptedException {1319 join(0);1320 }1321

1322 /**

1323 * Prints a stack trace of the current thread to the standard error stream.1324 * This method is used only for debugging.1325 *1326 *@seeThrowable#printStackTrace()1327 */

1328 public static voiddumpStack() {1329 new Exception("Stack trace").printStackTrace();1330 }1331

1332 /**

1333 * Marks this thread as either a {@linkplain#isDaemon daemon} thread1334 * or a user thread. The Java Virtual Machine exits when the only1335 * threads running are all daemon threads.1336 *1337 *

This method must be invoked before the thread is started.1338 *1339 *@paramon1340 * if {@codetrue}, marks this thread as a daemon thread1341 *1342 *@throwsIllegalThreadStateException1343 * if this thread is {@linkplain#isAlive alive}1344 *1345 *@throwsSecurityException1346 * if {@link#checkAccess} determines that the current1347 * thread cannot modify this thread1348 */

1349 public final void setDaemon(booleanon) {1350 checkAccess();1351 if(isAlive()) {1352 throw newIllegalThreadStateException();1353 }1354 daemon =on;1355 }1356

1357 /**

1358 * Tests if this thread is a daemon thread.1359 *1360 *@returntrue if this thread is a daemon thread;1361 * false otherwise.1362 *@see#setDaemon(boolean)1363 */

1364 public final booleanisDaemon() {1365 returndaemon;1366 }1367

1368 /**

1369 * Determines if the currently running thread has permission to1370 * modify this thread.1371 *

1372 * If there is a security manager, its checkAccess method1373 * is called with this thread as its argument. This may result in1374 * throwing a SecurityException.1375 *1376 *@exceptionSecurityException if the current thread is not allowed to1377 * access this thread.1378 *@seeSecurityManager#checkAccess(Thread)1379 */

1380 public final voidcheckAccess() {1381 SecurityManager security =System.getSecurityManager();1382 if (security != null) {1383 security.checkAccess(this);1384 }1385 }1386

1387 /**

1388 * Returns a string representation of this thread, including the1389 * thread's name, priority, and thread group.1390 *1391 *@returna string representation of this thread.1392 */

1393 publicString toString() {1394 ThreadGroup group =getThreadGroup();1395 if (group != null) {1396 return "Thread[" + getName() + "," + getPriority() + "," +

1397 group.getName() + "]";1398 } else{1399 return "Thread[" + getName() + "," + getPriority() + "," +

1400 "" + "]";1401 }1402 }1403

1404 /**

1405 * Returns the context ClassLoader for this Thread. The context1406 * ClassLoader is provided by the creator of the thread for use1407 * by code running in this thread when loading classes and resources.1408 * If not {@linkplain#setContextClassLoader set}, the default is the1409 * ClassLoader context of the parent Thread. The context ClassLoader of the1410 * primordial thread is typically set to the class loader used to load the1411 * application.1412 *1413 *

If a security manager is present, and the invoker's class loader is not1414 * {@codenull} and is not the same as or an ancestor of the context class1415 * loader, then this method invokes the security manager's {@link

1416 * SecurityManager#checkPermission(java.security.Permission) checkPermission}1417 * method with a {@linkRuntimePermission RuntimePermission}{@code

1418 * ("getClassLoader")} permission to verify that retrieval of the context1419 * class loader is permitted.1420 *1421 *@returnthe context ClassLoader for this Thread, or {@codenull}1422 * indicating the system class loader (or, failing that, the1423 * bootstrap class loader)1424 *1425 *@throwsSecurityException1426 * if the current thread cannot get the context ClassLoader1427 *1428 *@since1.21429 */

1430 @CallerSensitive1431 publicClassLoader getContextClassLoader() {1432 if (contextClassLoader == null)1433 return null;1434 SecurityManager sm =System.getSecurityManager();1435 if (sm != null) {1436 ClassLoader.checkClassLoaderPermission(contextClassLoader,1437 Reflection.getCallerClass());1438 }1439 returncontextClassLoader;1440 }1441

1442 /**

1443 * Sets the context ClassLoader for this Thread. The context1444 * ClassLoader can be set when a thread is created, and allows1445 * the creator of the thread to provide the appropriate class loader,1446 * through {@codegetContextClassLoader}, to code running in the thread1447 * when loading classes and resources.1448 *1449 *

If a security manager is present, its {@link

1450 * SecurityManager#checkPermission(java.security.Permission) checkPermission}1451 * method is invoked with a {@linkRuntimePermission RuntimePermission}{@code

1452 * ("setContextClassLoader")} permission to see if setting the context1453 * ClassLoader is permitted.1454 *1455 *@paramcl1456 * the context ClassLoader for this Thread, or null indicating the1457 * system class loader (or, failing that, the bootstrap class loader)1458 *1459 *@throwsSecurityException1460 * if the current thread cannot set the context ClassLoader1461 *1462 *@since1.21463 */

1464 public voidsetContextClassLoader(ClassLoader cl) {1465 SecurityManager sm =System.getSecurityManager();1466 if (sm != null) {1467 sm.checkPermission(new RuntimePermission("setContextClassLoader"));1468 }1469 contextClassLoader =cl;1470 }1471

1472 /**

1473 * Returns true if and only if the current thread holds the1474 * monitor lock on the specified object.1475 *1476 *

This method is designed to allow a program to assert that1477 * the current thread already holds a specified lock:1478 *

1479 *     assert Thread.holdsLock(obj);1480 * 
1481 *1482 *@paramobj the object on which to test lock ownership1483 *@throwsNullPointerException if obj is null1484 *@return true if the current thread holds the monitor lock on1485 * the specified object.1486 *@since1.41487 */

1488 public static native booleanholdsLock(Object obj);1489

1490 private static finalStackTraceElement[] EMPTY_STACK_TRACE1491 = new StackTraceElement[0];1492

1493 /**

1494 * Returns an array of stack trace elements representing the stack dump1495 * of this thread. This method will return a zero-length array if1496 * this thread has not started, has started but has not yet been1497 * scheduled to run by the system, or has terminated.1498 * If the returned array is of non-zero length then the first element of1499 * the array represents the top of the stack, which is the most recent1500 * method invocation in the sequence. The last element of the array1501 * represents the bottom of the stack, which is the least recent method1502 * invocation in the sequence.1503 *1504 *

If there is a security manager, and this thread is not1505 * the current thread, then the security manager's1506 * checkPermission method is called with a1507 * RuntimePermission("getStackTrace") permission1508 * to see if it's ok to get the stack trace.1509 *1510 *

Some virtual machines may, under some circumstances, omit one1511 * or more stack frames from the stack trace. In the extreme case,1512 * a virtual machine that has no stack trace information concerning1513 * this thread is permitted to return a zero-length array from this1514 * method.1515 *1516 *@returnan array of StackTraceElement,1517 * each represents one stack frame.1518 *1519 *@throwsSecurityException1520 * if a security manager exists and its1521 * checkPermission method doesn't allow1522 * getting the stack trace of thread.1523 *@seeSecurityManager#checkPermission1524 *@seeRuntimePermission1525 *@seeThrowable#getStackTrace1526 *1527 *@since1.51528 */

1529 publicStackTraceElement[] getStackTrace() {1530 if (this !=Thread.currentThread()) {1531 //check for getStackTrace permission

1532 SecurityManager security =System.getSecurityManager();1533 if (security != null) {1534 security.checkPermission(1535 SecurityConstants.GET_STACK_TRACE_PERMISSION);1536 }1537 //optimization so we do not call into the vm for threads that1538 //have not yet started or have terminated

1539 if (!isAlive()) {1540 returnEMPTY_STACK_TRACE;1541 }1542 StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});1543 StackTraceElement[] stackTrace = stackTraceArray[0];1544 //a thread that was alive during the previous isAlive call may have1545 //since terminated, therefore not having a stacktrace.

1546 if (stackTrace == null) {1547 stackTrace =EMPTY_STACK_TRACE;1548 }1549 returnstackTrace;1550 } else{1551 //Don't need JVM help for current thread

1552 return (newException()).getStackTrace();1553 }1554 }1555

1556 /**

1557 * Returns a map of stack traces for all live threads.1558 * The map keys are threads and each map value is an array of1559 * StackTraceElement that represents the stack dump1560 * of the corresponding Thread.1561 * The returned stack traces are in the format specified for1562 * the {@link#getStackTrace getStackTrace} method.1563 *1564 *

The threads may be executing while this method is called.1565 * The stack trace of each thread only represents a snapshot and1566 * each stack trace may be obtained at different time. A zero-length1567 * array will be returned in the map value if the virtual machine has1568 * no stack trace information about a thread.1569 *1570 *

If there is a security manager, then the security manager's1571 * checkPermission method is called with a1572 * RuntimePermission("getStackTrace") permission as well as1573 * RuntimePermission("modifyThreadGroup") permission1574 * to see if it is ok to get the stack trace of all threads.1575 *1576 *@returna Map from Thread to an array of1577 * StackTraceElement that represents the stack trace of1578 * the corresponding thread.1579 *1580 *@throwsSecurityException1581 * if a security manager exists and its1582 * checkPermission method doesn't allow1583 * getting the stack trace of thread.1584 *@see#getStackTrace1585 *@seeSecurityManager#checkPermission1586 *@seeRuntimePermission1587 *@seeThrowable#getStackTrace1588 *1589 *@since1.51590 */

1591 public static MapgetAllStackTraces() {1592 //check for getStackTrace permission

1593 SecurityManager security =System.getSecurityManager();1594 if (security != null) {1595 security.checkPermission(1596 SecurityConstants.GET_STACK_TRACE_PERMISSION);1597 security.checkPermission(1598 SecurityConstants.MODIFY_THREADGROUP_PERMISSION);1599 }1600

1601 //Get a snapshot of the list of all threads

1602 Thread[] threads =getThreads();1603 StackTraceElement[][] traces =dumpThreads(threads);1604 Map m = new HashMap<>(threads.length);1605 for (int i = 0; i < threads.length; i++) {1606 StackTraceElement[] stackTrace =traces[i];1607 if (stackTrace != null) {1608 m.put(threads[i], stackTrace);1609 }1610 //else terminated so we don't put it in the map

1611 }1612 returnm;1613 }1614

1615

1616 private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =

1617 new RuntimePermission("enableContextClassLoaderOverride");1618

1619 /**cache of subclass security audit results*/

1620 /*Replace with ConcurrentReferenceHashMap when/if it appears in a future1621 * release*/

1622 private static classCaches {1623 /**cache of subclass security audit results*/

1624 static final ConcurrentMap subclassAudits =

1625 new ConcurrentHashMap<>();1626

1627 /**queue for WeakReferences to audited subclasses*/

1628 static final ReferenceQueue> subclassAuditsQueue =

1629 new ReferenceQueue<>();1630 }1631

1632 /**

1633 * Verifies that this (possibly subclass) instance can be constructed1634 * without violating security constraints: the subclass must not override1635 * security-sensitive non-final methods, or else the1636 * "enableContextClassLoaderOverride" RuntimePermission is checked.1637 */

1638 private static boolean isCCLOverridden(Class>cl) {1639 if (cl == Thread.class)1640 return false;1641

1642 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);1643 WeakClassKey key = newWeakClassKey(cl, Caches.subclassAuditsQueue);1644 Boolean result =Caches.subclassAudits.get(key);1645 if (result == null) {1646 result =Boolean.valueOf(auditSubclass(cl));1647 Caches.subclassAudits.putIfAbsent(key, result);1648 }1649

1650 returnresult.booleanValue();1651 }1652

1653 /**

1654 * Performs reflective checks on given subclass to verify that it doesn't1655 * override security-sensitive non-final methods. Returns true if the1656 * subclass overrides any of the methods, false otherwise.1657 */

1658 private static boolean auditSubclass(final Class>subcl) {1659 Boolean result =AccessController.doPrivileged(1660 new PrivilegedAction() {1661 publicBoolean run() {1662 for (Class> cl =subcl;1663 cl != Thread.class;1664 cl =cl.getSuperclass())1665 {1666 try{1667 cl.getDeclaredMethod("getContextClassLoader", new Class>[0]);1668 returnBoolean.TRUE;1669 } catch(NoSuchMethodException ex) {1670 }1671 try{1672 Class>[] params = {ClassLoader.class};1673 cl.getDeclaredMethod("setContextClassLoader", params);1674 returnBoolean.TRUE;1675 } catch(NoSuchMethodException ex) {1676 }1677 }1678 returnBoolean.FALSE;1679 }1680 }1681 );1682 returnresult.booleanValue();1683 }1684

1685 private native staticStackTraceElement[][] dumpThreads(Thread[] threads);1686 private native staticThread[] getThreads();1687

1688 /**

1689 * Returns the identifier of this Thread. The thread ID is a positive1690 * long number generated when this thread was created.1691 * The thread ID is unique and remains unchanged during its lifetime.1692 * When a thread is terminated, this thread ID may be reused.1693 *1694 *@returnthis thread's ID.1695 *@since1.51696 */

1697 public longgetId() {1698 returntid;1699 }1700

1701 /**

1702 * A thread state. A thread can be in one of the following states:1703 *

  • 1704 *
  • {@link#NEW}
    1705 * A thread that has not yet started is in this state.1706 * 1707 *
  • {@link#RUNNABLE}
    1708 * A thread executing in the Java virtual machine is in this state.1709 * 1710 *
  • {@link#BLOCKED}
    1711 * A thread that is blocked waiting for a monitor lock1712 * is in this state.1713 * 1714 *
  • {@link#WAITING}
    1715 * A thread that is waiting indefinitely for another thread to1716 * perform a particular action is in this state.1717 * 1718 *
  • {@link#TIMED_WAITING}
    1719 * A thread that is waiting for another thread to perform an action1720 * for up to a specified waiting time is in this state.1721 * 1722 *
  • {@link#TERMINATED}
    1723 * A thread that has exited is in this state.1724 * 1725 *
1726 *1727 *

1728 * A thread can be in only one state at a given point in time.1729 * These states are virtual machine states which do not reflect1730 * any operating system thread states.1731 *1732 *@since1.51733 *@see#getState1734 */

1735 public enumState {1736 /**

1737 * Thread state for a thread which has not yet started.1738 */

1739 NEW,1740

1741 /**

1742 * Thread state for a runnable thread. A thread in the runnable1743 * state is executing in the Java virtual machine but it may1744 * be waiting for other resources from the operating system1745 * such as processor.1746 */

1747 RUNNABLE,1748

1749 /**

1750 * Thread state for a thread blocked waiting for a monitor lock.1751 * A thread in the blocked state is waiting for a monitor lock1752 * to enter a synchronized block/method or1753 * reenter a synchronized block/method after calling1754 * {@linkObject#wait() Object.wait}.1755 */

1756 BLOCKED,1757

1758 /**

1759 * Thread state for a waiting thread.1760 * A thread is in the waiting state due to calling one of the1761 * following methods:1762 *

  • 1763 *
  • {@linkObject#wait() Object.wait} with no timeout1764 *
  • {@link#join() Thread.join} with no timeout1765 *
  • {@linkLockSupport#park() LockSupport.park}1766 *
1767 *1768 *

A thread in the waiting state is waiting for another thread to1769 * perform a particular action.1770 *1771 * For example, a thread that has called Object.wait()1772 * on an object is waiting for another thread to call1773 * Object.notify() or Object.notifyAll() on1774 * that object. A thread that has called Thread.join()1775 * is waiting for a specified thread to terminate.1776 */

1777 WAITING,1778

1779 /**

1780 * Thread state for a waiting thread with a specified waiting time.1781 * A thread is in the timed waiting state due to calling one of1782 * the following methods with a specified positive waiting time:1783 *

  • 1784 *
  • {@link#sleep Thread.sleep}1785 *
  • {@linkObject#wait(long) Object.wait} with timeout1786 *
  • {@link#join(long) Thread.join} with timeout1787 *
  • {@linkLockSupport#parkNanos LockSupport.parkNanos}1788 *
  • {@linkLockSupport#parkUntil LockSupport.parkUntil}1789 *
1790 */

1791 TIMED_WAITING,1792

1793 /**

1794 * Thread state for a terminated thread.1795 * The thread has completed execution.1796 */

1797 TERMINATED;1798 }1799

1800 /**

1801 * Returns the state of this thread.1802 * This method is designed for use in monitoring of the system state,1803 * not for synchronization control.1804 *1805 *@returnthis thread's state.1806 *@since1.51807 */

1808 publicState getState() {1809 //get current thread state

1810 returnsun.misc.VM.toThreadState(threadStatus);1811 }1812

1813 //Added in JSR-166

1814

1815 /**

1816 * Interface for handlers invoked when a Thread abruptly1817 * terminates due to an uncaught exception.1818 *

When a thread is about to terminate due to an uncaught exception1819 * the Java Virtual Machine will query the thread for its1820 * UncaughtExceptionHandler using1821 * {@link#getUncaughtExceptionHandler} and will invoke the handler's1822 * uncaughtException method, passing the thread and the1823 * exception as arguments.1824 * If a thread has not had its UncaughtExceptionHandler1825 * explicitly set, then its ThreadGroup object acts as its1826 * UncaughtExceptionHandler. If the ThreadGroup object1827 * has no1828 * special requirements for dealing with the exception, it can forward1829 * the invocation to the {@linkplain#getDefaultUncaughtExceptionHandler1830 * default uncaught exception handler}.1831 *1832 *@see#setDefaultUncaughtExceptionHandler1833 *@see#setUncaughtExceptionHandler1834 *@seeThreadGroup#uncaughtException1835 *@since1.51836 */

1837 @FunctionalInterface1838 public interfaceUncaughtExceptionHandler {1839 /**

1840 * Method invoked when the given thread terminates due to the1841 * given uncaught exception.1842 *

Any exception thrown by this method will be ignored by the1843 * Java Virtual Machine.1844 *@paramt the thread1845 *@parame the exception1846 */

1847 voiduncaughtException(Thread t, Throwable e);1848 }1849

1850 //null unless explicitly set

1851 private volatileUncaughtExceptionHandler uncaughtExceptionHandler;1852

1853 //null unless explicitly set

1854 private static volatileUncaughtExceptionHandler defaultUncaughtExceptionHandler;1855

1856 /**

1857 * Set the default handler invoked when a thread abruptly terminates1858 * due to an uncaught exception, and no other handler has been defined1859 * for that thread.1860 *1861 *

Uncaught exception handling is controlled first by the thread, then1862 * by the thread's {@linkThreadGroup} object and finally by the default1863 * uncaught exception handler. If the thread does not have an explicit1864 * uncaught exception handler set, and the thread's thread group1865 * (including parent thread groups) does not specialize its1866 * uncaughtException method, then the default handler's1867 * uncaughtException method will be invoked.1868 *

By setting the default uncaught exception handler, an application1869 * can change the way in which uncaught exceptions are handled (such as1870 * logging to a specific device, or file) for those threads that would1871 * already accept whatever "default" behavior the system1872 * provided.1873 *1874 *

Note that the default uncaught exception handler should not usually1875 * defer to the thread's ThreadGroup object, as that could cause1876 * infinite recursion.1877 *1878 *@parameh the object to use as the default uncaught exception handler.1879 * If null then there is no default handler.1880 *1881 *@throwsSecurityException if a security manager is present and it1882 * denies {@linkRuntimePermission}1883 * ("setDefaultUncaughtExceptionHandler")1884 *1885 *@see#setUncaughtExceptionHandler1886 *@see#getUncaughtExceptionHandler1887 *@seeThreadGroup#uncaughtException1888 *@since1.51889 */

1890 public static voidsetDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {1891 SecurityManager sm =System.getSecurityManager();1892 if (sm != null) {1893 sm.checkPermission(1894 new RuntimePermission("setDefaultUncaughtExceptionHandler")1895 );1896 }1897

1898 defaultUncaughtExceptionHandler =eh;1899 }1900

1901 /**

1902 * Returns the default handler invoked when a thread abruptly terminates1903 * due to an uncaught exception. If the returned value is null,1904 * there is no default.1905 *@since1.51906 *@see#setDefaultUncaughtExceptionHandler1907 *@returnthe default uncaught exception handler for all threads1908 */

1909 public staticUncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){1910 returndefaultUncaughtExceptionHandler;1911 }1912

1913 /**

1914 * Returns the handler invoked when this thread abruptly terminates1915 * due to an uncaught exception. If this thread has not had an1916 * uncaught exception handler explicitly set then this thread's1917 * ThreadGroup object is returned, unless this thread1918 * has terminated, in which case null is returned.1919 *@since1.51920 *@returnthe uncaught exception handler for this thread1921 */

1922 publicUncaughtExceptionHandler getUncaughtExceptionHandler() {1923 return uncaughtExceptionHandler != null ?

1924 uncaughtExceptionHandler : group;1925 }1926

1927 /**

1928 * Set the handler invoked when this thread abruptly terminates1929 * due to an uncaught exception.1930 *

A thread can take full control of how it responds to uncaught1931 * exceptions by having its uncaught exception handler explicitly set.1932 * If no such handler is set then the thread's ThreadGroup1933 * object acts as its handler.1934 *@parameh the object to use as this thread's uncaught exception1935 * handler. If null then this thread has no explicit handler.1936 *@throwsSecurityException if the current thread is not allowed to1937 * modify this thread.1938 *@see#setDefaultUncaughtExceptionHandler1939 *@seeThreadGroup#uncaughtException1940 *@since1.51941 */

1942 public voidsetUncaughtExceptionHandler(UncaughtExceptionHandler eh) {1943 checkAccess();1944 uncaughtExceptionHandler =eh;1945 }1946

1947 /**

1948 * Dispatch an uncaught exception to the handler. This method is1949 * intended to be called only by the JVM.1950 */

1951 private voiddispatchUncaughtException(Throwable e) {1952 getUncaughtExceptionHandler().uncaughtException(this, e);1953 }1954

1955 /**

1956 * Removes from the specified map any keys that have been enqueued1957 * on the specified reference queue.1958 */

1959 static void processQueue(ReferenceQueue>queue,1960 ConcurrentMap extends

1961 WeakReference>, ?>map)1962 {1963 Reference extends Class>>ref;1964 while((ref = queue.poll()) != null) {1965 map.remove(ref);1966 }1967 }1968

1969 /**

1970 * Weak key for Class objects.1971 **/

1972 static class WeakClassKey extends WeakReference>{1973 /**

1974 * saved value of the referent's identity hash code, to maintain1975 * a consistent hash code after the referent has been cleared1976 */

1977 private final inthash;1978

1979 /**

1980 * Create a new WeakClassKey to the given object, registered1981 * with a queue.1982 */

1983 WeakClassKey(Class> cl, ReferenceQueue>refQueue) {1984 super(cl, refQueue);1985 hash =System.identityHashCode(cl);1986 }1987

1988 /**

1989 * Returns the identity hash code of the original referent.1990 */

1991 @Override1992 public inthashCode() {1993 returnhash;1994 }1995

1996 /**

1997 * Returns true if the given object is this identical1998 * WeakClassKey instance, or, if this object's referent has not1999 * been cleared, if the given object is another WeakClassKey2000 * instance with the identical non-null referent as this one.2001 */

2002 @Override2003 public booleanequals(Object obj) {2004 if (obj == this)2005 return true;2006

2007 if (obj instanceofWeakClassKey) {2008 Object referent =get();2009 return (referent != null) &&

2010 (referent ==((WeakClassKey) obj).get());2011 } else{2012 return false;2013 }2014 }2015 }2016

2017

2018 //The following three initially uninitialized fields are exclusively2019 //managed by class java.util.concurrent.ThreadLocalRandom. These2020 //fields are used to build the high-performance PRNGs in the2021 //concurrent code, and we can not risk accidental false sharing.2022 //Hence, the fields are isolated with @Contended.

2023

2024 /**The current seed for a ThreadLocalRandom*/

2025 @sun.misc.Contended("tlr")2026 longthreadLocalRandomSeed;2027

2028 /**Probe hash value; nonzero if threadLocalRandomSeed initialized*/

2029 @sun.misc.Contended("tlr")2030 intthreadLocalRandomProbe;2031

2032 /**Secondary seed isolated from public ThreadLocalRandom sequence*/

2033 @sun.misc.Contended("tlr")2034 intthreadLocalRandomSecondarySeed;2035

2036 /*Some private helper methods*/

2037 private native void setPriority0(intnewPriority);2038 private native voidstop0(Object o);2039 private native voidsuspend0();2040 private native voidresume0();2041 private native voidinterrupt0();2042 private native voidsetNativeName(String name);2043 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值