2
|
1 |
/*
|
|
2 |
* Copyright 1994-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation. Sun designates this
|
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
|
9 |
* by Sun in the LICENSE file that accompanied this code.
|
|
10 |
*
|
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
15 |
* accompanied this code).
|
|
16 |
*
|
|
17 |
* You should have received a copy of the GNU General Public License version
|
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
20 |
*
|
|
21 |
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
23 |
* have any questions.
|
|
24 |
*/
|
|
25 |
|
|
26 |
package java.lang;
|
|
27 |
|
|
28 |
import java.security.AccessController;
|
|
29 |
import java.security.AccessControlContext;
|
|
30 |
import java.security.PrivilegedAction;
|
|
31 |
import java.util.Map;
|
|
32 |
import java.util.HashMap;
|
|
33 |
import java.util.Collections;
|
|
34 |
import java.util.concurrent.locks.LockSupport;
|
|
35 |
import sun.misc.SoftCache;
|
|
36 |
import sun.nio.ch.Interruptible;
|
|
37 |
import sun.security.util.SecurityConstants;
|
|
38 |
|
|
39 |
|
|
40 |
/**
|
|
41 |
* A <i>thread</i> is a thread of execution in a program. The Java
|
|
42 |
* Virtual Machine allows an application to have multiple threads of
|
|
43 |
* execution running concurrently.
|
|
44 |
* <p>
|
|
45 |
* Every thread has a priority. Threads with higher priority are
|
|
46 |
* executed in preference to threads with lower priority. Each thread
|
|
47 |
* may or may not also be marked as a daemon. When code running in
|
|
48 |
* some thread creates a new <code>Thread</code> object, the new
|
|
49 |
* thread has its priority initially set equal to the priority of the
|
|
50 |
* creating thread, and is a daemon thread if and only if the
|
|
51 |
* creating thread is a daemon.
|
|
52 |
* <p>
|
|
53 |
* When a Java Virtual Machine starts up, there is usually a single
|
|
54 |
* non-daemon thread (which typically calls the method named
|
|
55 |
* <code>main</code> of some designated class). The Java Virtual
|
|
56 |
* Machine continues to execute threads until either of the following
|
|
57 |
* occurs:
|
|
58 |
* <ul>
|
|
59 |
* <li>The <code>exit</code> method of class <code>Runtime</code> has been
|
|
60 |
* called and the security manager has permitted the exit operation
|
|
61 |
* to take place.
|
|
62 |
* <li>All threads that are not daemon threads have died, either by
|
|
63 |
* returning from the call to the <code>run</code> method or by
|
|
64 |
* throwing an exception that propagates beyond the <code>run</code>
|
|
65 |
* method.
|
|
66 |
* </ul>
|
|
67 |
* <p>
|
|
68 |
* There are two ways to create a new thread of execution. One is to
|
|
69 |
* declare a class to be a subclass of <code>Thread</code>. This
|
|
70 |
* subclass should override the <code>run</code> method of class
|
|
71 |
* <code>Thread</code>. An instance of the subclass can then be
|
|
72 |
* allocated and started. For example, a thread that computes primes
|
|
73 |
* larger than a stated value could be written as follows:
|
|
74 |
* <p><hr><blockquote><pre>
|
|
75 |
* class PrimeThread extends Thread {
|
|
76 |
* long minPrime;
|
|
77 |
* PrimeThread(long minPrime) {
|
|
78 |
* this.minPrime = minPrime;
|
|
79 |
* }
|
|
80 |
*
|
|
81 |
* public void run() {
|
|
82 |
* // compute primes larger than minPrime
|
|
83 |
* . . .
|
|
84 |
* }
|
|
85 |
* }
|
|
86 |
* </pre></blockquote><hr>
|
|
87 |
* <p>
|
|
88 |
* The following code would then create a thread and start it running:
|
|
89 |
* <p><blockquote><pre>
|
|
90 |
* PrimeThread p = new PrimeThread(143);
|
|
91 |
* p.start();
|
|
92 |
* </pre></blockquote>
|
|
93 |
* <p>
|
|
94 |
* The other way to create a thread is to declare a class that
|
|
95 |
* implements the <code>Runnable</code> interface. That class then
|
|
96 |
* implements the <code>run</code> method. An instance of the class can
|
|
97 |
* then be allocated, passed as an argument when creating
|
|
98 |
* <code>Thread</code>, and started. The same example in this other
|
|
99 |
* style looks like the following:
|
|
100 |
* <p><hr><blockquote><pre>
|
|
101 |
* class PrimeRun implements Runnable {
|
|
102 |
* long minPrime;
|
|
103 |
* PrimeRun(long minPrime) {
|
|
104 |
* this.minPrime = minPrime;
|
|
105 |
* }
|
|
106 |
*
|
|
107 |
* public void run() {
|
|
108 |
* // compute primes larger than minPrime
|
|
109 |
* . . .
|
|
110 |
* }
|
|
111 |
* }
|
|
112 |
* </pre></blockquote><hr>
|
|
113 |
* <p>
|
|
114 |
* The following code would then create a thread and start it running:
|
|
115 |
* <p><blockquote><pre>
|
|
116 |
* PrimeRun p = new PrimeRun(143);
|
|
117 |
* new Thread(p).start();
|
|
118 |
* </pre></blockquote>
|
|
119 |
* <p>
|
|
120 |
* Every thread has a name for identification purposes. More than
|
|
121 |
* one thread may have the same name. If a name is not specified when
|
|
122 |
* a thread is created, a new name is generated for it.
|
|
123 |
*
|
|
124 |
* @author unascribed
|
|
125 |
* @see Runnable
|
|
126 |
* @see Runtime#exit(int)
|
|
127 |
* @see #run()
|
|
128 |
* @see #stop()
|
|
129 |
* @since JDK1.0
|
|
130 |
*/
|
|
131 |
public
|
|
132 |
class Thread implements Runnable {
|
|
133 |
/* Make sure registerNatives is the first thing <clinit> does. */
|
|
134 |
private static native void registerNatives();
|
|
135 |
static {
|
|
136 |
registerNatives();
|
|
137 |
}
|
|
138 |
|
|
139 |
private char name[];
|
|
140 |
private int priority;
|
|
141 |
private Thread threadQ;
|
|
142 |
private long eetop;
|
|
143 |
|
|
144 |
/* Whether or not to single_step this thread. */
|
|
145 |
private boolean single_step;
|
|
146 |
|
|
147 |
/* Whether or not the thread is a daemon thread. */
|
|
148 |
private boolean daemon = false;
|
|
149 |
|
|
150 |
/* JVM state */
|
|
151 |
private boolean stillborn = false;
|
|
152 |
|
|
153 |
/* What will be run. */
|
|
154 |
private Runnable target;
|
|
155 |
|
|
156 |
/* The group of this thread */
|
|
157 |
private ThreadGroup group;
|
|
158 |
|
|
159 |
/* The context ClassLoader for this thread */
|
|
160 |
private ClassLoader contextClassLoader;
|
|
161 |
|
|
162 |
/* The inherited AccessControlContext of this thread */
|
|
163 |
private AccessControlContext inheritedAccessControlContext;
|
|
164 |
|
|
165 |
/* For autonumbering anonymous threads. */
|
|
166 |
private static int threadInitNumber;
|
|
167 |
private static synchronized int nextThreadNum() {
|
|
168 |
return threadInitNumber++;
|
|
169 |
}
|
|
170 |
|
|
171 |
/* ThreadLocal values pertaining to this thread. This map is maintained
|
|
172 |
* by the ThreadLocal class. */
|
|
173 |
ThreadLocal.ThreadLocalMap threadLocals = null;
|
|
174 |
|
|
175 |
/*
|
|
176 |
* InheritableThreadLocal values pertaining to this thread. This map is
|
|
177 |
* maintained by the InheritableThreadLocal class.
|
|
178 |
*/
|
|
179 |
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
|
|
180 |
|
|
181 |
/*
|
|
182 |
* The requested stack size for this thread, or 0 if the creator did
|
|
183 |
* not specify a stack size. It is up to the VM to do whatever it
|
|
184 |
* likes with this number; some VMs will ignore it.
|
|
185 |
*/
|
|
186 |
private long stackSize;
|
|
187 |
|
|
188 |
/*
|
|
189 |
* JVM-private state that persists after native thread termination.
|
|
190 |
*/
|
|
191 |
private long nativeParkEventPointer;
|
|
192 |
|
|
193 |
/*
|
|
194 |
* Thread ID
|
|
195 |
*/
|
|
196 |
private long tid;
|
|
197 |
|
|
198 |
/* For generating thread ID */
|
|
199 |
private static long threadSeqNumber;
|
|
200 |
|
|
201 |
/* Java thread status for tools,
|
|
202 |
* initialized to indicate thread 'not yet started'
|
|
203 |
*/
|
|
204 |
|
|
205 |
private int threadStatus = 0;
|
|
206 |
|
|
207 |
|
|
208 |
private static synchronized long nextThreadID() {
|
|
209 |
return ++threadSeqNumber;
|
|
210 |
}
|
|
211 |
|
|
212 |
/**
|
|
213 |
* The argument supplied to the current call to
|
|
214 |
* java.util.concurrent.locks.LockSupport.park.
|
|
215 |
* Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
|
|
216 |
* Accessed using java.util.concurrent.locks.LockSupport.getBlocker
|
|
217 |
*/
|
|
218 |
volatile Object parkBlocker;
|
|
219 |
|
|
220 |
/* The object in which this thread is blocked in an interruptible I/O
|
|
221 |
* operation, if any. The blocker's interrupt method should be invoked
|
|
222 |
* after setting this thread's interrupt status.
|
|
223 |
*/
|
|
224 |
private volatile Interruptible blocker;
|
|
225 |
private Object blockerLock = new Object();
|
|
226 |
|
|
227 |
/* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
|
|
228 |
*/
|
|
229 |
void blockedOn(Interruptible b) {
|
|
230 |
synchronized (blockerLock) {
|
|
231 |
blocker = b;
|
|
232 |
}
|
|
233 |
}
|
|
234 |
|
|
235 |
/**
|
|
236 |
* The minimum priority that a thread can have.
|
|
237 |
*/
|
|
238 |
public final static int MIN_PRIORITY = 1;
|
|
239 |
|
|
240 |
/**
|
|
241 |
* The default priority that is assigned to a thread.
|
|
242 |
*/
|
|
243 |
public final static int NORM_PRIORITY = 5;
|
|
244 |
|
|
245 |
/**
|
|
246 |
* The maximum priority that a thread can have.
|
|
247 |
*/
|
|
248 |
public final static int MAX_PRIORITY = 10;
|
|
249 |
|
|
250 |
/* If stop was called before start */
|
|
251 |
private boolean stopBeforeStart;
|
|
252 |
|
|
253 |
/* Remembered Throwable from stop before start */
|
|
254 |
private Throwable throwableFromStop;
|
|
255 |
|
|
256 |
/**
|
|
257 |
* Returns a reference to the currently executing thread object.
|
|
258 |
*
|
|
259 |
* @return the currently executing thread.
|
|
260 |
*/
|
|
261 |
public static native Thread currentThread();
|
|
262 |
|
|
263 |
/**
|
|
264 |
* A hint to the scheduler that the current thread is willing to yield
|
|
265 |
* its current use of a processor. The scheduler is free to ignore this
|
|
266 |
* hint.
|
|
267 |
*
|
|
268 |
* <p> Yield is a heuristic attempt to improve relative progression
|
|
269 |
* between threads that would otherwise over-utilise a CPU. Its use
|
|
270 |
* should be combined with detailed profiling and benchmarking to
|
|
271 |
* ensure that it actually has the desired effect.
|
|
272 |
*
|
|
273 |
* <p> It is rarely appropriate to use this method. It may be useful
|
|
274 |
* for debugging or testing purposes, where it may help to reproduce
|
|
275 |
* bugs due to race conditions. It may also be useful when designing
|
|
276 |
* concurrency control constructs such as the ones in the
|
|
277 |
* {@link java.util.concurrent.locks} package.
|
|
278 |
*/
|
|
279 |
public static native void yield();
|
|
280 |
|
|
281 |
/**
|
|
282 |
* Causes the currently executing thread to sleep (temporarily cease
|
|
283 |
* execution) for the specified number of milliseconds, subject to
|
|
284 |
* the precision and accuracy of system timers and schedulers. The thread
|
|
285 |
* does not lose ownership of any monitors.
|
|
286 |
*
|
|
287 |
* @param millis
|
|
288 |
* the length of time to sleep in milliseconds
|
|
289 |
*
|
|
290 |
* @throws IllegalArgumentException
|
|
291 |
* if the value of {@code millis} is negative
|
|
292 |
*
|
|
293 |
* @throws InterruptedException
|
|
294 |
* if any thread has interrupted the current thread. The
|
|
295 |
* <i>interrupted status</i> of the current thread is
|
|
296 |
* cleared when this exception is thrown.
|
|
297 |
*/
|
|
298 |
public static native void sleep(long millis) throws InterruptedException;
|
|
299 |
|
|
300 |
/**
|
|
301 |
* Causes the currently executing thread to sleep (temporarily cease
|
|
302 |
* execution) for the specified number of milliseconds plus the specified
|
|
303 |
* number of nanoseconds, subject to the precision and accuracy of system
|
|
304 |
* timers and schedulers. The thread does not lose ownership of any
|
|
305 |
* monitors.
|
|
306 |
*
|
|
307 |
* @param millis
|
|
308 |
* the length of time to sleep in milliseconds
|
|
309 |
*
|
|
310 |
* @param nanos
|
|
311 |
* {@code 0-999999} additional nanoseconds to sleep
|
|
312 |
*
|
|
313 |
* @throws IllegalArgumentException
|
|
314 |
* if the value of {@code millis} is negative, or the value of
|
|
315 |
* {@code nanos} is not in the range {@code 0-999999}
|
|
316 |
*
|
|
317 |
* @throws InterruptedException
|
|
318 |
* if any thread has interrupted the current thread. The
|
|
319 |
* <i>interrupted status</i> of the current thread is
|
|
320 |
* cleared when this exception is thrown.
|
|
321 |
*/
|
|
322 |
public static void sleep(long millis, int nanos)
|
|
323 |
throws InterruptedException {
|
|
324 |
if (millis < 0) {
|
|
325 |
throw new IllegalArgumentException("timeout value is negative");
|
|
326 |
}
|
|
327 |
|
|
328 |
if (nanos < 0 || nanos > 999999) {
|
|
329 |
throw new IllegalArgumentException(
|
|
330 |
"nanosecond timeout value out of range");
|
|
331 |
}
|
|
332 |
|
|
333 |
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
|
|
334 |
millis++;
|
|
335 |
}
|
|
336 |
|
|
337 |
sleep(millis);
|
|
338 |
}
|
|
339 |
|
|
340 |
/**
|
|
341 |
* Initializes a Thread.
|
|
342 |
*
|
|
343 |
* @param g the Thread group
|
|
344 |
* @param target the object whose run() method gets called
|
|
345 |
* @param name the name of the new Thread
|
|
346 |
* @param stackSize the desired stack size for the new thread, or
|
|
347 |
* zero to indicate that this parameter is to be ignored.
|
|
348 |
*/
|
|
349 |
private void init(ThreadGroup g, Runnable target, String name,
|
|
350 |
long stackSize) {
|
|
351 |
Thread parent = currentThread();
|
|
352 |
SecurityManager security = System.getSecurityManager();
|
|
353 |
if (g == null) {
|
|
354 |
/* Determine if it's an applet or not */
|
|
355 |
|
|
356 |
/* If there is a security manager, ask the security manager
|
|
357 |
what to do. */
|
|
358 |
if (security != null) {
|
|
359 |
g = security.getThreadGroup();
|
|
360 |
}
|
|
361 |
|
|
362 |
/* If the security doesn't have a strong opinion of the matter
|
|
363 |
use the parent thread group. */
|
|
364 |
if (g == null) {
|
|
365 |
g = parent.getThreadGroup();
|
|
366 |
}
|
|
367 |
}
|
|
368 |
|
|
369 |
/* checkAccess regardless of whether or not threadgroup is
|
|
370 |
explicitly passed in. */
|
|
371 |
g.checkAccess();
|
|
372 |
|
|
373 |
/*
|
|
374 |
* Do we have the required permissions?
|
|
375 |
*/
|
|
376 |
if (security != null) {
|
|
377 |
if (isCCLOverridden(getClass())) {
|
|
378 |
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
|
|
379 |
}
|
|
380 |
}
|
|
381 |
|
|
382 |
|
|
383 |
g.addUnstarted();
|
|
384 |
|
|
385 |
this.group = g;
|
|
386 |
this.daemon = parent.isDaemon();
|
|
387 |
this.priority = parent.getPriority();
|
|
388 |
this.name = name.toCharArray();
|
|
389 |
if (security == null || isCCLOverridden(parent.getClass()))
|
|
390 |
this.contextClassLoader = parent.getContextClassLoader();
|
|
391 |
else
|
|
392 |
this.contextClassLoader = parent.contextClassLoader;
|
|
393 |
this.inheritedAccessControlContext = AccessController.getContext();
|
|
394 |
this.target = target;
|
|
395 |
setPriority(priority);
|
|
396 |
if (parent.inheritableThreadLocals != null)
|
|
397 |
this.inheritableThreadLocals =
|
|
398 |
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
|
|
399 |
/* Stash the specified stack size in case the VM cares */
|
|
400 |
this.stackSize = stackSize;
|
|
401 |
|
|
402 |
/* Set thread ID */
|
|
403 |
tid = nextThreadID();
|
|
404 |
}
|
|
405 |
|
|
406 |
/**
|
|
407 |
* Allocates a new <code>Thread</code> object. This constructor has
|
|
408 |
* the same effect as <code>Thread(null, null,</code>
|
|
409 |
* <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
|
|
410 |
* a newly generated name. Automatically generated names are of the
|
|
411 |
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
|
|
412 |
*
|
|
413 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
414 |
*/
|
|
415 |
public Thread() {
|
|
416 |
init(null, null, "Thread-" + nextThreadNum(), 0);
|
|
417 |
}
|
|
418 |
|
|
419 |
/**
|
|
420 |
* Allocates a new <code>Thread</code> object. This constructor has
|
|
421 |
* the same effect as <code>Thread(null, target,</code>
|
|
422 |
* <i>gname</i><code>)</code>, where <i>gname</i> is
|
|
423 |
* a newly generated name. Automatically generated names are of the
|
|
424 |
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
|
|
425 |
*
|
|
426 |
* @param target the object whose <code>run</code> method is called.
|
|
427 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
428 |
*/
|
|
429 |
public Thread(Runnable target) {
|
|
430 |
init(null, target, "Thread-" + nextThreadNum(), 0);
|
|
431 |
}
|
|
432 |
|
|
433 |
/**
|
|
434 |
* Allocates a new <code>Thread</code> object. This constructor has
|
|
435 |
* the same effect as <code>Thread(group, target,</code>
|
|
436 |
* <i>gname</i><code>)</code>, where <i>gname</i> is
|
|
437 |
* a newly generated name. Automatically generated names are of the
|
|
438 |
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
|
|
439 |
*
|
|
440 |
* @param group the thread group.
|
|
441 |
* @param target the object whose <code>run</code> method is called.
|
|
442 |
* @exception SecurityException if the current thread cannot create a
|
|
443 |
* thread in the specified thread group.
|
|
444 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
445 |
*/
|
|
446 |
public Thread(ThreadGroup group, Runnable target) {
|
|
447 |
init(group, target, "Thread-" + nextThreadNum(), 0);
|
|
448 |
}
|
|
449 |
|
|
450 |
/**
|
|
451 |
* Allocates a new <code>Thread</code> object. This constructor has
|
|
452 |
* the same effect as <code>Thread(null, null, name)</code>.
|
|
453 |
*
|
|
454 |
* @param name the name of the new thread.
|
|
455 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
456 |
*/
|
|
457 |
public Thread(String name) {
|
|
458 |
init(null, null, name, 0);
|
|
459 |
}
|
|
460 |
|
|
461 |
/**
|
|
462 |
* Allocates a new <code>Thread</code> object. This constructor has
|
|
463 |
* the same effect as <code>Thread(group, null, name)</code>
|
|
464 |
*
|
|
465 |
* @param group the thread group.
|
|
466 |
* @param name the name of the new thread.
|
|
467 |
* @exception SecurityException if the current thread cannot create a
|
|
468 |
* thread in the specified thread group.
|
|
469 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
470 |
*/
|
|
471 |
public Thread(ThreadGroup group, String name) {
|
|
472 |
init(group, null, name, 0);
|
|
473 |
}
|
|
474 |
|
|
475 |
/**
|
|
476 |
* Allocates a new <code>Thread</code> object. This constructor has
|
|
477 |
* the same effect as <code>Thread(null, target, name)</code>.
|
|
478 |
*
|
|
479 |
* @param target the object whose <code>run</code> method is called.
|
|
480 |
* @param name the name of the new thread.
|
|
481 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
482 |
*/
|
|
483 |
public Thread(Runnable target, String name) {
|
|
484 |
init(null, target, name, 0);
|
|
485 |
}
|
|
486 |
|
|
487 |
/**
|
|
488 |
* Allocates a new <code>Thread</code> object so that it has
|
|
489 |
* <code>target</code> as its run object, has the specified
|
|
490 |
* <code>name</code> as its name, and belongs to the thread group
|
|
491 |
* referred to by <code>group</code>.
|
|
492 |
* <p>
|
|
493 |
* If <code>group</code> is <code>null</code> and there is a
|
|
494 |
* security manager, the group is determined by the security manager's
|
|
495 |
* <code>getThreadGroup</code> method. If <code>group</code> is
|
|
496 |
* <code>null</code> and there is not a security manager, or the
|
|
497 |
* security manager's <code>getThreadGroup</code> method returns
|
|
498 |
* <code>null</code>, the group is set to be the same ThreadGroup
|
|
499 |
* as the thread that is creating the new thread.
|
|
500 |
*
|
|
501 |
* <p>If there is a security manager, its <code>checkAccess</code>
|
|
502 |
* method is called with the ThreadGroup as its argument.
|
|
503 |
* <p>In addition, its <code>checkPermission</code>
|
|
504 |
* method is called with the
|
|
505 |
* <code>RuntimePermission("enableContextClassLoaderOverride")</code>
|
|
506 |
* permission when invoked directly or indirectly by the constructor
|
|
507 |
* of a subclass which overrides the <code>getContextClassLoader</code>
|
|
508 |
* or <code>setContextClassLoader</code> methods.
|
|
509 |
* This may result in a SecurityException.
|
|
510 |
|
|
511 |
* <p>
|
|
512 |
* If the <code>target</code> argument is not <code>null</code>, the
|
|
513 |
* <code>run</code> method of the <code>target</code> is called when
|
|
514 |
* this thread is started. If the target argument is
|
|
515 |
* <code>null</code>, this thread's <code>run</code> method is called
|
|
516 |
* when this thread is started.
|
|
517 |
* <p>
|
|
518 |
* The priority of the newly created thread is set equal to the
|
|
519 |
* priority of the thread creating it, that is, the currently running
|
|
520 |
* thread. The method <code>setPriority</code> may be used to
|
|
521 |
* change the priority to a new value.
|
|
522 |
* <p>
|
|
523 |
* The newly created thread is initially marked as being a daemon
|
|
524 |
* thread if and only if the thread creating it is currently marked
|
|
525 |
* as a daemon thread. The method <code>setDaemon </code> may be used
|
|
526 |
* to change whether or not a thread is a daemon.
|
|
527 |
*
|
|
528 |
* @param group the thread group.
|
|
529 |
* @param target the object whose <code>run</code> method is called.
|
|
530 |
* @param name the name of the new thread.
|
|
531 |
* @exception SecurityException if the current thread cannot create a
|
|
532 |
* thread in the specified thread group or cannot
|
|
533 |
* override the context class loader methods.
|
|
534 |
* @see Runnable#run()
|
|
535 |
* @see #run()
|
|
536 |
* @see #setDaemon(boolean)
|
|
537 |
* @see #setPriority(int)
|
|
538 |
* @see ThreadGroup#checkAccess()
|
|
539 |
* @see SecurityManager#checkAccess
|
|
540 |
*/
|
|
541 |
public Thread(ThreadGroup group, Runnable target, String name) {
|
|
542 |
init(group, target, name, 0);
|
|
543 |
}
|
|
544 |
|
|
545 |
/**
|
|
546 |
* Allocates a new <code>Thread</code> object so that it has
|
|
547 |
* <code>target</code> as its run object, has the specified
|
|
548 |
* <code>name</code> as its name, belongs to the thread group referred to
|
|
549 |
* by <code>group</code>, and has the specified <i>stack size</i>.
|
|
550 |
*
|
|
551 |
* <p>This constructor is identical to {@link
|
|
552 |
* #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
|
|
553 |
* that it allows the thread stack size to be specified. The stack size
|
|
554 |
* is the approximate number of bytes of address space that the virtual
|
|
555 |
* machine is to allocate for this thread's stack. <b>The effect of the
|
|
556 |
* <tt>stackSize</tt> parameter, if any, is highly platform dependent.</b>
|
|
557 |
*
|
|
558 |
* <p>On some platforms, specifying a higher value for the
|
|
559 |
* <tt>stackSize</tt> parameter may allow a thread to achieve greater
|
|
560 |
* recursion depth before throwing a {@link StackOverflowError}.
|
|
561 |
* Similarly, specifying a lower value may allow a greater number of
|
|
562 |
* threads to exist concurrently without throwing an {@link
|
|
563 |
* OutOfMemoryError} (or other internal error). The details of
|
|
564 |
* the relationship between the value of the <tt>stackSize</tt> parameter
|
|
565 |
* and the maximum recursion depth and concurrency level are
|
|
566 |
* platform-dependent. <b>On some platforms, the value of the
|
|
567 |
* <tt>stackSize</tt> parameter may have no effect whatsoever.</b>
|
|
568 |
*
|
|
569 |
* <p>The virtual machine is free to treat the <tt>stackSize</tt>
|
|
570 |
* parameter as a suggestion. If the specified value is unreasonably low
|
|
571 |
* for the platform, the virtual machine may instead use some
|
|
572 |
* platform-specific minimum value; if the specified value is unreasonably
|
|
573 |
* high, the virtual machine may instead use some platform-specific
|
|
574 |
* maximum. Likewise, the virtual machine is free to round the specified
|
|
575 |
* value up or down as it sees fit (or to ignore it completely).
|
|
576 |
*
|
|
577 |
* <p>Specifying a value of zero for the <tt>stackSize</tt> parameter will
|
|
578 |
* cause this constructor to behave exactly like the
|
|
579 |
* <tt>Thread(ThreadGroup, Runnable, String)</tt> constructor.
|
|
580 |
*
|
|
581 |
* <p><i>Due to the platform-dependent nature of the behavior of this
|
|
582 |
* constructor, extreme care should be exercised in its use.
|
|
583 |
* The thread stack size necessary to perform a given computation will
|
|
584 |
* likely vary from one JRE implementation to another. In light of this
|
|
585 |
* variation, careful tuning of the stack size parameter may be required,
|
|
586 |
* and the tuning may need to be repeated for each JRE implementation on
|
|
587 |
* which an application is to run.</i>
|
|
588 |
*
|
|
589 |
* <p>Implementation note: Java platform implementers are encouraged to
|
|
590 |
* document their implementation's behavior with respect to the
|
|
591 |
* <tt>stackSize parameter</tt>.
|
|
592 |
*
|
|
593 |
* @param group the thread group.
|
|
594 |
* @param target the object whose <code>run</code> method is called.
|
|
595 |
* @param name the name of the new thread.
|
|
596 |
* @param stackSize the desired stack size for the new thread, or
|
|
597 |
* zero to indicate that this parameter is to be ignored.
|
|
598 |
* @exception SecurityException if the current thread cannot create a
|
|
599 |
* thread in the specified thread group.
|
|
600 |
* @since 1.4
|
|
601 |
*/
|
|
602 |
public Thread(ThreadGroup group, Runnable target, String name,
|
|
603 |
long stackSize) {
|
|
604 |
init(group, target, name, stackSize);
|
|
605 |
}
|
|
606 |
|
|
607 |
/**
|
|
608 |
* Causes this thread to begin execution; the Java Virtual Machine
|
|
609 |
* calls the <code>run</code> method of this thread.
|
|
610 |
* <p>
|
|
611 |
* The result is that two threads are running concurrently: the
|
|
612 |
* current thread (which returns from the call to the
|
|
613 |
* <code>start</code> method) and the other thread (which executes its
|
|
614 |
* <code>run</code> method).
|
|
615 |
* <p>
|
|
616 |
* It is never legal to start a thread more than once.
|
|
617 |
* In particular, a thread may not be restarted once it has completed
|
|
618 |
* execution.
|
|
619 |
*
|
|
620 |
* @exception IllegalThreadStateException if the thread was already
|
|
621 |
* started.
|
|
622 |
* @see #run()
|
|
623 |
* @see #stop()
|
|
624 |
*/
|
|
625 |
public synchronized void start() {
|
|
626 |
/**
|
|
627 |
* This method is not invoked for the main method thread or "system"
|
|
628 |
* group threads created/set up by the VM. Any new functionality added
|
|
629 |
* to this method in the future may have to also be added to the VM.
|
|
630 |
*
|
|
631 |
* A zero status value corresponds to state "NEW".
|
|
632 |
*/
|
|
633 |
if (threadStatus != 0)
|
|
634 |
throw new IllegalThreadStateException();
|
|
635 |
|
|
636 |
/* Notify the group that this thread is about to be started
|
|
637 |
* so that it can be added to the group's list of threads. */
|
|
638 |
group.threadStarting(this);
|
|
639 |
|
|
640 |
boolean failed = true;
|
|
641 |
try {
|
|
642 |
start0();
|
|
643 |
failed = false;
|
|
644 |
} finally {
|
|
645 |
try {
|
|
646 |
group.threadStarted(this, failed);
|
|
647 |
} catch (Throwable ignore) {
|
|
648 |
/* do nothing. If start0 threw a Throwable then
|
|
649 |
it will be passed up the call stack */
|
|
650 |
}
|
|
651 |
}
|
|
652 |
|
|
653 |
if (stopBeforeStart) {
|
|
654 |
stop0(throwableFromStop);
|
|
655 |
}
|
|
656 |
}
|
|
657 |
|
|
658 |
private native void start0();
|
|
659 |
|
|
660 |
/**
|
|
661 |
* If this thread was constructed using a separate
|
|
662 |
* <code>Runnable</code> run object, then that
|
|
663 |
* <code>Runnable</code> object's <code>run</code> method is called;
|
|
664 |
* otherwise, this method does nothing and returns.
|
|
665 |
* <p>
|
|
666 |
* Subclasses of <code>Thread</code> should override this method.
|
|
667 |
*
|
|
668 |
* @see #start()
|
|
669 |
* @see #stop()
|
|
670 |
* @see #Thread(ThreadGroup, Runnable, String)
|
|
671 |
*/
|
|
672 |
public void run() {
|
|
673 |
if (target != null) {
|
|
674 |
target.run();
|
|
675 |
}
|
|
676 |
}
|
|
677 |
|
|
678 |
/**
|
|
679 |
* This method is called by the system to give a Thread
|
|
680 |
* a chance to clean up before it actually exits.
|
|
681 |
*/
|
|
682 |
private void exit() {
|
|
683 |
if (group != null) {
|
|
684 |
group.threadTerminated(this);
|
|
685 |
group = null;
|
|
686 |
}
|
|
687 |
/* Aggressively null out all reference fields: see bug 4006245 */
|
|
688 |
target = null;
|
|
689 |
/* Speed the release of some of these resources */
|
|
690 |
threadLocals = null;
|
|
691 |
inheritableThreadLocals = null;
|
|
692 |
inheritedAccessControlContext = null;
|
|
693 |
blocker = null;
|
|
694 |
uncaughtExceptionHandler = null;
|
|
695 |
}
|
|
696 |
|
|
697 |
/**
|
|
698 |
* Forces the thread to stop executing.
|
|
699 |
* <p>
|
|
700 |
* If there is a security manager installed, its <code>checkAccess</code>
|
|
701 |
* method is called with <code>this</code>
|
|
702 |
* as its argument. This may result in a
|
|
703 |
* <code>SecurityException</code> being raised (in the current thread).
|
|
704 |
* <p>
|
|
705 |
* If this thread is different from the current thread (that is, the current
|
|
706 |
* thread is trying to stop a thread other than itself), the
|
|
707 |
* security manager's <code>checkPermission</code> method (with a
|
|
708 |
* <code>RuntimePermission("stopThread")</code> argument) is called in
|
|
709 |
* addition.
|
|
710 |
* Again, this may result in throwing a
|
|
711 |
* <code>SecurityException</code> (in the current thread).
|
|
712 |
* <p>
|
|
713 |
* The thread represented by this thread is forced to stop whatever
|
|
714 |
* it is doing abnormally and to throw a newly created
|
|
715 |
* <code>ThreadDeath</code> object as an exception.
|
|
716 |
* <p>
|
|
717 |
* It is permitted to stop a thread that has not yet been started.
|
|
718 |
* If the thread is eventually started, it immediately terminates.
|
|
719 |
* <p>
|
|
720 |
* An application should not normally try to catch
|
|
721 |
* <code>ThreadDeath</code> unless it must do some extraordinary
|
|
722 |
* cleanup operation (note that the throwing of
|
|
723 |
* <code>ThreadDeath</code> causes <code>finally</code> clauses of
|
|
724 |
* <code>try</code> statements to be executed before the thread
|
|
725 |
* officially dies). If a <code>catch</code> clause catches a
|
|
726 |
* <code>ThreadDeath</code> object, it is important to rethrow the
|
|
727 |
* object so that the thread actually dies.
|
|
728 |
* <p>
|
|
729 |
* The top-level error handler that reacts to otherwise uncaught
|
|
730 |
* exceptions does not print out a message or otherwise notify the
|
|
731 |
* application if the uncaught exception is an instance of
|
|
732 |
* <code>ThreadDeath</code>.
|
|
733 |
*
|
|
734 |
* @exception SecurityException if the current thread cannot
|
|
735 |
* modify this thread.
|
|
736 |
* @see #interrupt()
|
|
737 |
* @see #checkAccess()
|
|
738 |
* @see #run()
|
|
739 |
* @see #start()
|
|
740 |
* @see ThreadDeath
|
|
741 |
* @see ThreadGroup#uncaughtException(Thread,Throwable)
|
|
742 |
* @see SecurityManager#checkAccess(Thread)
|
|
743 |
* @see SecurityManager#checkPermission
|
|
744 |
* @deprecated This method is inherently unsafe. Stopping a thread with
|
|
745 |
* Thread.stop causes it to unlock all of the monitors that it
|
|
746 |
* has locked (as a natural consequence of the unchecked
|
|
747 |
* <code>ThreadDeath</code> exception propagating up the stack). If
|
|
748 |
* any of the objects previously protected by these monitors were in
|
|
749 |
* an inconsistent state, the damaged objects become visible to
|
|
750 |
* other threads, potentially resulting in arbitrary behavior. Many
|
|
751 |
* uses of <code>stop</code> should be replaced by code that simply
|
|
752 |
* modifies some variable to indicate that the target thread should
|
|
753 |
* stop running. The target thread should check this variable
|
|
754 |
* regularly, and return from its run method in an orderly fashion
|
|
755 |
* if the variable indicates that it is to stop running. If the
|
|
756 |
* target thread waits for long periods (on a condition variable,
|
|
757 |
* for example), the <code>interrupt</code> method should be used to
|
|
758 |
* interrupt the wait.
|
|
759 |
* For more information, see
|
|
760 |
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
|
761 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
|
762 |
*/
|
|
763 |
@Deprecated
|
|
764 |
public final void stop() {
|
|
765 |
// If the thread is already dead, return.
|
|
766 |
// A zero status value corresponds to "NEW".
|
|
767 |
if ((threadStatus != 0) && !isAlive()) {
|
|
768 |
return;
|
|
769 |
}
|
|
770 |
stop1(new ThreadDeath());
|
|
771 |
}
|
|
772 |
|
|
773 |
/**
|
|
774 |
* Forces the thread to stop executing.
|
|
775 |
* <p>
|
|
776 |
* If there is a security manager installed, the <code>checkAccess</code>
|
|
777 |
* method of this thread is called, which may result in a
|
|
778 |
* <code>SecurityException</code> being raised (in the current thread).
|
|
779 |
* <p>
|
|
780 |
* If this thread is different from the current thread (that is, the current
|
|
781 |
* thread is trying to stop a thread other than itself) or
|
|
782 |
* <code>obj</code> is not an instance of <code>ThreadDeath</code>, the
|
|
783 |
* security manager's <code>checkPermission</code> method (with the
|
|
784 |
* <code>RuntimePermission("stopThread")</code> argument) is called in
|
|
785 |
* addition.
|
|
786 |
* Again, this may result in throwing a
|
|
787 |
* <code>SecurityException</code> (in the current thread).
|
|
788 |
* <p>
|
|
789 |
* If the argument <code>obj</code> is null, a
|
|
790 |
* <code>NullPointerException</code> is thrown (in the current thread).
|
|
791 |
* <p>
|
|
792 |
* The thread represented by this thread is forced to stop
|
|
793 |
* whatever it is doing abnormally and to throw the
|
|
794 |
* <code>Throwable</code> object <code>obj</code> as an exception. This
|
|
795 |
* is an unusual action to take; normally, the <code>stop</code> method
|
|
796 |
* that takes no arguments should be used.
|
|
797 |
* <p>
|
|
798 |
* It is permitted to stop a thread that has not yet been started.
|
|
799 |
* If the thread is eventually started, it immediately terminates.
|
|
800 |
*
|
|
801 |
* @param obj the Throwable object to be thrown.
|
|
802 |
* @exception SecurityException if the current thread cannot modify
|
|
803 |
* this thread.
|
|
804 |
* @throws NullPointerException if obj is <tt>null</tt>.
|
|
805 |
* @see #interrupt()
|
|
806 |
* @see #checkAccess()
|
|
807 |
* @see #run()
|
|
808 |
* @see #start()
|
|
809 |
* @see #stop()
|
|
810 |
* @see SecurityManager#checkAccess(Thread)
|
|
811 |
* @see SecurityManager#checkPermission
|
|
812 |
* @deprecated This method is inherently unsafe. See {@link #stop()}
|
|
813 |
* for details. An additional danger of this
|
|
814 |
* method is that it may be used to generate exceptions that the
|
|
815 |
* target thread is unprepared to handle (including checked
|
|
816 |
* exceptions that the thread could not possibly throw, were it
|
|
817 |
* not for this method).
|
|
818 |
* For more information, see
|
|
819 |
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
|
820 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
|
821 |
*/
|
|
822 |
@Deprecated
|
|
823 |
public final synchronized void stop(Throwable obj) {
|
|
824 |
stop1(obj);
|
|
825 |
}
|
|
826 |
|
|
827 |
/**
|
|
828 |
* Common impl for stop() and stop(Throwable).
|
|
829 |
*/
|
|
830 |
private final synchronized void stop1(Throwable th) {
|
|
831 |
SecurityManager security = System.getSecurityManager();
|
|
832 |
if (security != null) {
|
|
833 |
checkAccess();
|
|
834 |
if ((this != Thread.currentThread()) ||
|
|
835 |
(!(th instanceof ThreadDeath))) {
|
|
836 |
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
|
|
837 |
}
|
|
838 |
}
|
|
839 |
// A zero status value corresponds to "NEW"
|
|
840 |
if (threadStatus != 0) {
|
|
841 |
resume(); // Wake up thread if it was suspended; no-op otherwise
|
|
842 |
stop0(th);
|
|
843 |
} else {
|
|
844 |
|
|
845 |
// Must do the null arg check that the VM would do with stop0
|
|
846 |
if (th == null) {
|
|
847 |
throw new NullPointerException();
|
|
848 |
}
|
|
849 |
|
|
850 |
// Remember this stop attempt for if/when start is used
|
|
851 |
stopBeforeStart = true;
|
|
852 |
throwableFromStop = th;
|
|
853 |
}
|
|
854 |
}
|
|
855 |
|
|
856 |
/**
|
|
857 |
* Interrupts this thread.
|
|
858 |
*
|
|
859 |
* <p> Unless the current thread is interrupting itself, which is
|
|
860 |
* always permitted, the {@link #checkAccess() checkAccess} method
|
|
861 |
* of this thread is invoked, which may cause a {@link
|
|
862 |
* SecurityException} to be thrown.
|
|
863 |
*
|
|
864 |
* <p> If this thread is blocked in an invocation of the {@link
|
|
865 |
* Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
|
|
866 |
* Object#wait(long, int) wait(long, int)} methods of the {@link Object}
|
|
867 |
* class, or of the {@link #join()}, {@link #join(long)}, {@link
|
|
868 |
* #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
|
|
869 |
* methods of this class, then its interrupt status will be cleared and it
|
|
870 |
* will receive an {@link InterruptedException}.
|
|
871 |
*
|
|
872 |
* <p> If this thread is blocked in an I/O operation upon an {@link
|
|
873 |
* java.nio.channels.InterruptibleChannel </code>interruptible
|
|
874 |
* channel<code>} then the channel will be closed, the thread's interrupt
|
|
875 |
* status will be set, and the thread will receive a {@link
|
|
876 |
* java.nio.channels.ClosedByInterruptException}.
|
|
877 |
*
|
|
878 |
* <p> If this thread is blocked in a {@link java.nio.channels.Selector}
|
|
879 |
* then the thread's interrupt status will be set and it will return
|
|
880 |
* immediately from the selection operation, possibly with a non-zero
|
|
881 |
* value, just as if the selector's {@link
|
|
882 |
* java.nio.channels.Selector#wakeup wakeup} method were invoked.
|
|
883 |
*
|
|
884 |
* <p> If none of the previous conditions hold then this thread's interrupt
|
|
885 |
* status will be set. </p>
|
|
886 |
*
|
|
887 |
* <p> Interrupting a thread that is not alive need not have any effect.
|
|
888 |
*
|
|
889 |
* @throws SecurityException
|
|
890 |
* if the current thread cannot modify this thread
|
|
891 |
*
|
|
892 |
* @revised 6.0
|
|
893 |
* @spec JSR-51
|
|
894 |
*/
|
|
895 |
public void interrupt() {
|
|
896 |
if (this != Thread.currentThread())
|
|
897 |
checkAccess();
|
|
898 |
|
|
899 |
synchronized (blockerLock) {
|
|
900 |
Interruptible b = blocker;
|
|
901 |
if (b != null) {
|
|
902 |
interrupt0(); // Just to set the interrupt flag
|
|
903 |
b.interrupt();
|
|
904 |
return;
|
|
905 |
}
|
|
906 |
}
|
|
907 |
interrupt0();
|
|
908 |
}
|
|
909 |
|
|
910 |
/**
|
|
911 |
* Tests whether the current thread has been interrupted. The
|
|
912 |
* <i>interrupted status</i> of the thread is cleared by this method. In
|
|
913 |
* other words, if this method were to be called twice in succession, the
|
|
914 |
* second call would return false (unless the current thread were
|
|
915 |
* interrupted again, after the first call had cleared its interrupted
|
|
916 |
* status and before the second call had examined it).
|
|
917 |
*
|
|
918 |
* <p>A thread interruption ignored because a thread was not alive
|
|
919 |
* at the time of the interrupt will be reflected by this method
|
|
920 |
* returning false.
|
|
921 |
*
|
|
922 |
* @return <code>true</code> if the current thread has been interrupted;
|
|
923 |
* <code>false</code> otherwise.
|
|
924 |
* @see #isInterrupted()
|
|
925 |
* @revised 6.0
|
|
926 |
*/
|
|
927 |
public static boolean interrupted() {
|
|
928 |
return currentThread().isInterrupted(true);
|
|
929 |
}
|
|
930 |
|
|
931 |
/**
|
|
932 |
* Tests whether this thread has been interrupted. The <i>interrupted
|
|
933 |
* status</i> of the thread is unaffected by this method.
|
|
934 |
*
|
|
935 |
* <p>A thread interruption ignored because a thread was not alive
|
|
936 |
* at the time of the interrupt will be reflected by this method
|
|
937 |
* returning false.
|
|
938 |
*
|
|
939 |
* @return <code>true</code> if this thread has been interrupted;
|
|
940 |
* <code>false</code> otherwise.
|
|
941 |
* @see #interrupted()
|
|
942 |
* @revised 6.0
|
|
943 |
*/
|
|
944 |
public boolean isInterrupted() {
|
|
945 |
return isInterrupted(false);
|
|
946 |
}
|
|
947 |
|
|
948 |
/**
|
|
949 |
* Tests if some Thread has been interrupted. The interrupted state
|
|
950 |
* is reset or not based on the value of ClearInterrupted that is
|
|
951 |
* passed.
|
|
952 |
*/
|
|
953 |
private native boolean isInterrupted(boolean ClearInterrupted);
|
|
954 |
|
|
955 |
/**
|
|
956 |
* Throws {@link NoSuchMethodError}.
|
|
957 |
*
|
|
958 |
* @deprecated This method was originally designed to destroy this
|
|
959 |
* thread without any cleanup. Any monitors it held would have
|
|
960 |
* remained locked. However, the method was never implemented.
|
|
961 |
* If if were to be implemented, it would be deadlock-prone in
|
|
962 |
* much the manner of {@link #suspend}. If the target thread held
|
|
963 |
* a lock protecting a critical system resource when it was
|
|
964 |
* destroyed, no thread could ever access this resource again.
|
|
965 |
* If another thread ever attempted to lock this resource, deadlock
|
|
966 |
* would result. Such deadlocks typically manifest themselves as
|
|
967 |
* "frozen" processes. For more information, see
|
|
968 |
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
|
|
969 |
* Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
|
970 |
* @throws NoSuchMethodError always
|
|
971 |
*/
|
|
972 |
@Deprecated
|
|
973 |
public void destroy() {
|
|
974 |
throw new NoSuchMethodError();
|
|
975 |
}
|
|
976 |
|
|
977 |
/**
|
|
978 |
* Tests if this thread is alive. A thread is alive if it has
|
|
979 |
* been started and has not yet died.
|
|
980 |
*
|
|
981 |
* @return <code>true</code> if this thread is alive;
|
|
982 |
* <code>false</code> otherwise.
|
|
983 |
*/
|
|
984 |
public final native boolean isAlive();
|
|
985 |
|
|
986 |
/**
|
|
987 |
* Suspends this thread.
|
|
988 |
* <p>
|
|
989 |
* First, the <code>checkAccess</code> method of this thread is called
|
|
990 |
* with no arguments. This may result in throwing a
|
|
991 |
* <code>SecurityException </code>(in the current thread).
|
|
992 |
* <p>
|
|
993 |
* If the thread is alive, it is suspended and makes no further
|
|
994 |
* progress unless and until it is resumed.
|
|
995 |
*
|
|
996 |
* @exception SecurityException if the current thread cannot modify
|
|
997 |
* this thread.
|
|
998 |
* @see #checkAccess
|
|
999 |
* @deprecated This method has been deprecated, as it is
|
|
1000 |
* inherently deadlock-prone. If the target thread holds a lock on the
|
|
1001 |
* monitor protecting a critical system resource when it is suspended, no
|
|
1002 |
* thread can access this resource until the target thread is resumed. If
|
|
1003 |
* the thread that would resume the target thread attempts to lock this
|
|
1004 |
* monitor prior to calling <code>resume</code>, deadlock results. Such
|
|
1005 |
* deadlocks typically manifest themselves as "frozen" processes.
|
|
1006 |
* For more information, see
|
|
1007 |
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
|
1008 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
|
1009 |
*/
|
|
1010 |
@Deprecated
|
|
1011 |
public final void suspend() {
|
|
1012 |
checkAccess();
|
|
1013 |
suspend0();
|
|
1014 |
}
|
|
1015 |
|
|
1016 |
/**
|
|
1017 |
* Resumes a suspended thread.
|
|
1018 |
* <p>
|
|
1019 |
* First, the <code>checkAccess</code> method of this thread is called
|
|
1020 |
* with no arguments. This may result in throwing a
|
|
1021 |
* <code>SecurityException</code> (in the current thread).
|
|
1022 |
* <p>
|
|
1023 |
* If the thread is alive but suspended, it is resumed and is
|
|
1024 |
* permitted to make progress in its execution.
|
|
1025 |
*
|
|
1026 |
* @exception SecurityException if the current thread cannot modify this
|
|
1027 |
* thread.
|
|
1028 |
* @see #checkAccess
|
|
1029 |
* @see #suspend()
|
|
1030 |
* @deprecated This method exists solely for use with {@link #suspend},
|
|
1031 |
* which has been deprecated because it is deadlock-prone.
|
|
1032 |
* For more information, see
|
|
1033 |
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
|
1034 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
|
1035 |
*/
|
|
1036 |
@Deprecated
|
|
1037 |
public final void resume() {
|
|
1038 |
checkAccess();
|
|
1039 |
resume0();
|
|
1040 |
}
|
|
1041 |
|
|
1042 |
/**
|
|
1043 |
* Changes the priority of this thread.
|
|
1044 |
* <p>
|
|
1045 |
* First the <code>checkAccess</code> method of this thread is called
|
|
1046 |
* with no arguments. This may result in throwing a
|
|
1047 |
* <code>SecurityException</code>.
|
|
1048 |
* <p>
|
|
1049 |
* Otherwise, the priority of this thread is set to the smaller of
|
|
1050 |
* the specified <code>newPriority</code> and the maximum permitted
|
|
1051 |
* priority of the thread's thread group.
|
|
1052 |
*
|
|
1053 |
* @param newPriority priority to set this thread to
|
|
1054 |
* @exception IllegalArgumentException If the priority is not in the
|
|
1055 |
* range <code>MIN_PRIORITY</code> to
|
|
1056 |
* <code>MAX_PRIORITY</code>.
|
|
1057 |
* @exception SecurityException if the current thread cannot modify
|
|
1058 |
* this thread.
|
|
1059 |
* @see #getPriority
|
|
1060 |
* @see #checkAccess()
|
|
1061 |
* @see #getThreadGroup()
|
|
1062 |
* @see #MAX_PRIORITY
|
|
1063 |
* @see #MIN_PRIORITY
|
|
1064 |
* @see ThreadGroup#getMaxPriority()
|
|
1065 |
*/
|
|
1066 |
public final void setPriority(int newPriority) {
|
|
1067 |
ThreadGroup g;
|
|
1068 |
checkAccess();
|
|
1069 |
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
|
|
1070 |
throw new IllegalArgumentException();
|
|
1071 |
}
|
|
1072 |
if((g = getThreadGroup()) != null) {
|
|
1073 |
if (newPriority > g.getMaxPriority()) {
|
|
1074 |
newPriority = g.getMaxPriority();
|
|
1075 |
}
|
|
1076 |
setPriority0(priority = newPriority);
|
|
1077 |
}
|
|
1078 |
}
|
|
1079 |
|
|
1080 |
/**
|
|
1081 |
* Returns this thread's priority.
|
|
1082 |
*
|
|
1083 |
* @return this thread's priority.
|
|
1084 |
* @see #setPriority
|
|
1085 |
*/
|
|
1086 |
public final int getPriority() {
|
|
1087 |
return priority;
|
|
1088 |
}
|
|
1089 |
|
|
1090 |
/**
|
|
1091 |
* Changes the name of this thread to be equal to the argument
|
|
1092 |
* <code>name</code>.
|
|
1093 |
* <p>
|
|
1094 |
* First the <code>checkAccess</code> method of this thread is called
|
|
1095 |
* with no arguments. This may result in throwing a
|
|
1096 |
* <code>SecurityException</code>.
|
|
1097 |
*
|
|
1098 |
* @param name the new name for this thread.
|
|
1099 |
* @exception SecurityException if the current thread cannot modify this
|
|
1100 |
* thread.
|
|
1101 |
* @see #getName
|
|
1102 |
* @see #checkAccess()
|
|
1103 |
*/
|
|
1104 |
public final void setName(String name) {
|
|
1105 |
checkAccess();
|
|
1106 |
this.name = name.toCharArray();
|
|
1107 |
}
|
|
1108 |
|
|
1109 |
/**
|
|
1110 |
* Returns this thread's name.
|
|
1111 |
*
|
|
1112 |
* @return this thread's name.
|
|
1113 |
* @see #setName(String)
|
|
1114 |
*/
|
|
1115 |
public final String getName() {
|
|
1116 |
return String.valueOf(name);
|
|
1117 |
}
|
|
1118 |
|
|
1119 |
/**
|
|
1120 |
* Returns the thread group to which this thread belongs.
|
|
1121 |
* This method returns null if this thread has died
|
|
1122 |
* (been stopped).
|
|
1123 |
*
|
|
1124 |
* @return this thread's thread group.
|
|
1125 |
*/
|
|
1126 |
public final ThreadGroup getThreadGroup() {
|
|
1127 |
return group;
|
|
1128 |
}
|
|
1129 |
|
|
1130 |
/**
|
|
1131 |
* Returns an estimate of the number of active threads in the current
|
|
1132 |
* thread's {@linkplain java.lang.ThreadGroup thread group} and its
|
|
1133 |
* subgroups. Recursively iterates over all subgroups in the current
|
|
1134 |
* thread's thread group.
|
|
1135 |
*
|
|
1136 |
* <p> The value returned is only an estimate because the number of
|
|
1137 |
* threads may change dynamically while this method traverses internal
|
|
1138 |
* data structures, and might be affected by the presence of certain
|
|
1139 |
* system threads. This method is intended primarily for debugging
|
|
1140 |
* and monitoring purposes.
|
|
1141 |
*
|
|
1142 |
* @return an estimate of the number of active threads in the current
|
|
1143 |
* thread's thread group and in any other thread group that
|
|
1144 |
* has the current thread's thread group as an ancestor
|
|
1145 |
*/
|
|
1146 |
public static int activeCount() {
|
|
1147 |
return currentThread().getThreadGroup().activeCount();
|
|
1148 |
}
|
|
1149 |
|
|
1150 |
/**
|
|
1151 |
* Copies into the specified array every active thread in the current
|
|
1152 |
* thread's thread group and its subgroups. This method simply
|
|
1153 |
* invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
|
|
1154 |
* method of the current thread's thread group.
|
|
1155 |
*
|
|
1156 |
* <p> An application might use the {@linkplain #activeCount activeCount}
|
|
1157 |
* method to get an estimate of how big the array should be, however
|
|
1158 |
* <i>if the array is too short to hold all the threads, the extra threads
|
|
1159 |
* are silently ignored.</i> If it is critical to obtain every active
|
|
1160 |
* thread in the current thread's thread group and its subgroups, the
|
|
1161 |
* invoker should verify that the returned int value is strictly less
|
|
1162 |
* than the length of {@code tarray}.
|
|
1163 |
*
|
|
1164 |
* <p> Due to the inherent race condition in this method, it is recommended
|
|
1165 |
* that the method only be used for debugging and monitoring purposes.
|
|
1166 |
*
|
|
1167 |
* @param tarray
|
|
1168 |
* an array into which to put the list of threads
|
|
1169 |
*
|
|
1170 |
* @return the number of threads put into the array
|
|
1171 |
*
|
|
1172 |
* @throws SecurityException
|
|
1173 |
* if {@link java.lang.ThreadGroup#checkAccess} determines that
|
|
1174 |
* the current thread cannot access its thread group
|
|
1175 |
*/
|
|
1176 |
public static int enumerate(Thread tarray[]) {
|
|
1177 |
return currentThread().getThreadGroup().enumerate(tarray);
|
|
1178 |
}
|
|
1179 |
|
|
1180 |
/**
|
|
1181 |
* Counts the number of stack frames in this thread. The thread must
|
|
1182 |
* be suspended.
|
|
1183 |
*
|
|
1184 |
* @return the number of stack frames in this thread.
|
|
1185 |
* @exception IllegalThreadStateException if this thread is not
|
|
1186 |
* suspended.
|
|
1187 |
* @deprecated The definition of this call depends on {@link #suspend},
|
|
1188 |
* which is deprecated. Further, the results of this call
|
|
1189 |
* were never well-defined.
|
|
1190 |
*/
|
|
1191 |
@Deprecated
|
|
1192 |
public native int countStackFrames();
|
|
1193 |
|
|
1194 |
/**
|
|
1195 |
* Waits at most {@code millis} milliseconds for this thread to
|
|
1196 |
* die. A timeout of {@code 0} means to wait forever.
|
|
1197 |
*
|
|
1198 |
* <p> This implementation uses a loop of {@code this.wait} calls
|
|
1199 |
* conditioned on {@code this.isAlive}. As a thread terminates the
|
|
1200 |
* {@code this.notifyAll} method is invoked. It is recommended that
|
|
1201 |
* applications not use {@code wait}, {@code notify}, or
|
|
1202 |
* {@code notifyAll} on {@code Thread} instances.
|
|
1203 |
*
|
|
1204 |
* @param millis
|
|
1205 |
* the time to wait in milliseconds
|
|
1206 |
*
|
|
1207 |
* @throws IllegalArgumentException
|
|
1208 |
* if the value of {@code millis} is negative
|
|
1209 |
*
|
|
1210 |
* @throws InterruptedException
|
|
1211 |
* if any thread has interrupted the current thread. The
|
|
1212 |
* <i>interrupted status</i> of the current thread is
|
|
1213 |
* cleared when this exception is thrown.
|
|
1214 |
*/
|
|
1215 |
public final synchronized void join(long millis)
|
|
1216 |
throws InterruptedException {
|
|
1217 |
long base = System.currentTimeMillis();
|
|
1218 |
long now = 0;
|
|
1219 |
|
|
1220 |
if (millis < 0) {
|
|
1221 |
throw new IllegalArgumentException("timeout value is negative");
|
|
1222 |
}
|
|
1223 |
|
|
1224 |
if (millis == 0) {
|
|
1225 |
while (isAlive()) {
|
|
1226 |
wait(0);
|
|
1227 |
}
|
|
1228 |
} else {
|
|
1229 |
while (isAlive()) {
|
|
1230 |
long delay = millis - now;
|
|
1231 |
if (delay <= 0) {
|
|
1232 |
break;
|
|
1233 |
}
|
|
1234 |
wait(delay);
|
|
1235 |
now = System.currentTimeMillis() - base;
|
|
1236 |
}
|
|
1237 |
}
|
|
1238 |
}
|
|
1239 |
|
|
1240 |
/**
|
|
1241 |
* Waits at most {@code millis} milliseconds plus
|
|
1242 |
* {@code nanos} nanoseconds for this thread to die.
|
|
1243 |
*
|
|
1244 |
* <p> This implementation uses a loop of {@code this.wait} calls
|
|
1245 |
* conditioned on {@code this.isAlive}. As a thread terminates the
|
|
1246 |
* {@code this.notifyAll} method is invoked. It is recommended that
|
|
1247 |
* applications not use {@code wait}, {@code notify}, or
|
|
1248 |
* {@code notifyAll} on {@code Thread} instances.
|
|
1249 |
*
|
|
1250 |
* @param millis
|
|
1251 |
* the time to wait in milliseconds
|
|
1252 |
*
|
|
1253 |
* @param nanos
|
|
1254 |
* {@code 0-999999} additional nanoseconds to wait
|
|
1255 |
*
|
|
1256 |
* @throws IllegalArgumentException
|
|
1257 |
* if the value of {@code millis} is negative, or the value
|
|
1258 |
* of {@code nanos} is not in the range {@code 0-999999}
|
|
1259 |
*
|
|
1260 |
* @throws InterruptedException
|
|
1261 |
* if any thread has interrupted the current thread. The
|
|
1262 |
* <i>interrupted status</i> of the current thread is
|
|
1263 |
* cleared when this exception is thrown.
|
|
1264 |
*/
|
|
1265 |
public final synchronized void join(long millis, int nanos)
|
|
1266 |
throws InterruptedException {
|
|
1267 |
|
|
1268 |
if (millis < 0) {
|
|
1269 |
throw new IllegalArgumentException("timeout value is negative");
|
|
1270 |
}
|
|
1271 |
|
|
1272 |
if (nanos < 0 || nanos > 999999) {
|
|
1273 |
throw new IllegalArgumentException(
|
|
1274 |
"nanosecond timeout value out of range");
|
|
1275 |
}
|
|
1276 |
|
|
1277 |
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
|
|
1278 |
millis++;
|
|
1279 |
}
|
|
1280 |
|
|
1281 |
join(millis);
|
|
1282 |
}
|
|
1283 |
|
|
1284 |
/**
|
|
1285 |
* Waits for this thread to die.
|
|
1286 |
*
|
|
1287 |
* <p> An invocation of this method behaves in exactly the same
|
|
1288 |
* way as the invocation
|
|
1289 |
*
|
|
1290 |
* <blockquote>
|
|
1291 |
* {@linkplain #join(long) join}{@code (0)}
|
|
1292 |
* </blockquote>
|
|
1293 |
*
|
|
1294 |
* @throws InterruptedException
|
|
1295 |
* if any thread has interrupted the current thread. The
|
|
1296 |
* <i>interrupted status</i> of the current thread is
|
|
1297 |
* cleared when this exception is thrown.
|
|
1298 |
*/
|
|
1299 |
public final void join() throws InterruptedException {
|
|
1300 |
join(0);
|
|
1301 |
}
|
|
1302 |
|
|
1303 |
/**
|
|
1304 |
* Prints a stack trace of the current thread to the standard error stream.
|
|
1305 |
* This method is used only for debugging.
|
|
1306 |
*
|
|
1307 |
* @see Throwable#printStackTrace()
|
|
1308 |
*/
|
|
1309 |
public static void dumpStack() {
|
|
1310 |
new Exception("Stack trace").printStackTrace();
|
|
1311 |
}
|
|
1312 |
|
|
1313 |
/**
|
|
1314 |
* Marks this thread as either a {@linkplain #isDaemon daemon} thread
|
|
1315 |
* or a user thread. The Java Virtual Machine exits when the only
|
|
1316 |
* threads running are all daemon threads.
|
|
1317 |
*
|
|
1318 |
* <p> This method must be invoked before the thread is started.
|
|
1319 |
*
|
|
1320 |
* @param on
|
|
1321 |
* if {@code true}, marks this thread as a daemon thread
|
|
1322 |
*
|
|
1323 |
* @throws IllegalThreadStateException
|
|
1324 |
* if this thread is {@linkplain #isAlive alive}
|
|
1325 |
*
|
|
1326 |
* @throws SecurityException
|
|
1327 |
* if {@link #checkAccess} determines that the current
|
|
1328 |
* thread cannot modify this thread
|
|
1329 |
*/
|
|
1330 |
public final void setDaemon(boolean on) {
|
|
1331 |
checkAccess();
|
|
1332 |
if (isAlive()) {
|
|
1333 |
throw new IllegalThreadStateException();
|
|
1334 |
}
|
|
1335 |
daemon = on;
|
|
1336 |
}
|
|
1337 |
|
|
1338 |
/**
|
|
1339 |
* Tests if this thread is a daemon thread.
|
|
1340 |
*
|
|
1341 |
* @return <code>true</code> if this thread is a daemon thread;
|
|
1342 |
* <code>false</code> otherwise.
|
|
1343 |
* @see #setDaemon(boolean)
|
|
1344 |
*/
|
|
1345 |
public final boolean isDaemon() {
|
|
1346 |
return daemon;
|
|
1347 |
}
|
|
1348 |
|
|
1349 |
/**
|
|
1350 |
* Determines if the currently running thread has permission to
|
|
1351 |
* modify this thread.
|
|
1352 |
* <p>
|
|
1353 |
* If there is a security manager, its <code>checkAccess</code> method
|
|
1354 |
* is called with this thread as its argument. This may result in
|
|
1355 |
* throwing a <code>SecurityException</code>.
|
|
1356 |
*
|
|
1357 |
* @exception SecurityException if the current thread is not allowed to
|
|
1358 |
* access this thread.
|
|
1359 |
* @see SecurityManager#checkAccess(Thread)
|
|
1360 |
*/
|
|
1361 |
public final void checkAccess() {
|
|
1362 |
SecurityManager security = System.getSecurityManager();
|
|
1363 |
if (security != null) {
|
|
1364 |
security.checkAccess(this);
|
|
1365 |
}
|
|
1366 |
}
|
|
1367 |
|
|
1368 |
/**
|
|
1369 |
* Returns a string representation of this thread, including the
|
|
1370 |
* thread's name, priority, and thread group.
|
|
1371 |
*
|
|
1372 |
* @return a string representation of this thread.
|
|
1373 |
*/
|
|
1374 |
public String toString() {
|
|
1375 |
ThreadGroup group = getThreadGroup();
|
|
1376 |
if (group != null) {
|
|
1377 |
return "Thread[" + getName() + "," + getPriority() + "," +
|
|
1378 |
group.getName() + "]";
|
|
1379 |
} else {
|
|
1380 |
return "Thread[" + getName() + "," + getPriority() + "," +
|
|
1381 |
"" + "]";
|
|
1382 |
}
|
|
1383 |
}
|
|
1384 |
|
|
1385 |
/**
|
|
1386 |
* Returns the context ClassLoader for this Thread. The context
|
|
1387 |
* ClassLoader is provided by the creator of the thread for use
|
|
1388 |
* by code running in this thread when loading classes and resources.
|
|
1389 |
* If not set, the default is the ClassLoader context of the parent
|
|
1390 |
* Thread. The context ClassLoader of the primordial thread is
|
|
1391 |
* typically set to the class loader used to load the application.
|
|
1392 |
*
|
|
1393 |
* <p>First, if there is a security manager, and the caller's class
|
|
1394 |
* loader is not null and the caller's class loader is not the same as or
|
|
1395 |
* an ancestor of the context class loader for the thread whose
|
|
1396 |
* context class loader is being requested, then the security manager's
|
|
1397 |
* <code>checkPermission</code>
|
|
1398 |
* method is called with a
|
|
1399 |
* <code>RuntimePermission("getClassLoader")</code> permission
|
|
1400 |
* to see if it's ok to get the context ClassLoader..
|
|
1401 |
*
|
|
1402 |
* @return the context ClassLoader for this Thread
|
|
1403 |
*
|
|
1404 |
* @throws SecurityException
|
|
1405 |
* if a security manager exists and its
|
|
1406 |
* <code>checkPermission</code> method doesn't allow
|
|
1407 |
* getting the context ClassLoader.
|
|
1408 |
* @see #setContextClassLoader
|
|
1409 |
* @see SecurityManager#checkPermission
|
|
1410 |
* @see RuntimePermission
|
|
1411 |
*
|
|
1412 |
* @since 1.2
|
|
1413 |
*/
|
|
1414 |
public ClassLoader getContextClassLoader() {
|
|
1415 |
if (contextClassLoader == null)
|
|
1416 |
return null;
|
|
1417 |
SecurityManager sm = System.getSecurityManager();
|
|
1418 |
if (sm != null) {
|
|
1419 |
ClassLoader ccl = ClassLoader.getCallerClassLoader();
|
|
1420 |
if (ccl != null && ccl != contextClassLoader &&
|
|
1421 |
!contextClassLoader.isAncestor(ccl)) {
|
|
1422 |
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
1423 |
}
|
|
1424 |
}
|
|
1425 |
return contextClassLoader;
|
|
1426 |
}
|
|
1427 |
|
|
1428 |
/**
|
|
1429 |
* Sets the context ClassLoader for this Thread. The context
|
|
1430 |
* ClassLoader can be set when a thread is created, and allows
|
|
1431 |
* the creator of the thread to provide the appropriate class loader
|
|
1432 |
* to code running in the thread when loading classes and resources.
|
|
1433 |
*
|
|
1434 |
* <p>First, if there is a security manager, its <code>checkPermission</code>
|
|
1435 |
* method is called with a
|
|
1436 |
* <code>RuntimePermission("setContextClassLoader")</code> permission
|
|
1437 |
* to see if it's ok to set the context ClassLoader..
|
|
1438 |
*
|
|
1439 |
* @param cl the context ClassLoader for this Thread
|
|
1440 |
*
|
|
1441 |
* @exception SecurityException if the current thread cannot set the
|
|
1442 |
* context ClassLoader.
|
|
1443 |
* @see #getContextClassLoader
|
|
1444 |
* @see SecurityManager#checkPermission
|
|
1445 |
* @see RuntimePermission
|
|
1446 |
*
|
|
1447 |
* @since 1.2
|
|
1448 |
*/
|
|
1449 |
public void setContextClassLoader(ClassLoader cl) {
|
|
1450 |
SecurityManager sm = System.getSecurityManager();
|
|
1451 |
if (sm != null) {
|
|
1452 |
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
|
|
1453 |
}
|
|
1454 |
contextClassLoader = cl;
|
|
1455 |
}
|
|
1456 |
|
|
1457 |
/**
|
|
1458 |
* Returns <tt>true</tt> if and only if the current thread holds the
|
|
1459 |
* monitor lock on the specified object.
|
|
1460 |
*
|
|
1461 |
* <p>This method is designed to allow a program to assert that
|
|
1462 |
* the current thread already holds a specified lock:
|
|
1463 |
* <pre>
|
|
1464 |
* assert Thread.holdsLock(obj);
|
|
1465 |
* </pre>
|
|
1466 |
*
|
|
1467 |
* @param obj the object on which to test lock ownership
|
|
1468 |
* @throws NullPointerException if obj is <tt>null</tt>
|
|
1469 |
* @return <tt>true</tt> if the current thread holds the monitor lock on
|
|
1470 |
* the specified object.
|
|
1471 |
* @since 1.4
|
|
1472 |
*/
|
|
1473 |
public static native boolean holdsLock(Object obj);
|
|
1474 |
|
|
1475 |
private static final StackTraceElement[] EMPTY_STACK_TRACE
|
|
1476 |
= new StackTraceElement[0];
|
|
1477 |
|
|
1478 |
/**
|
|
1479 |
* Returns an array of stack trace elements representing the stack dump
|
|
1480 |
* of this thread. This method will return a zero-length array if
|
|
1481 |
* this thread has not started, has started but has not yet been
|
|
1482 |
* scheduled to run by the system, or has terminated.
|
|
1483 |
* If the returned array is of non-zero length then the first element of
|
|
1484 |
* the array represents the top of the stack, which is the most recent
|
|
1485 |
* method invocation in the sequence. The last element of the array
|
|
1486 |
* represents the bottom of the stack, which is the least recent method
|
|
1487 |
* invocation in the sequence.
|
|
1488 |
*
|
|
1489 |
* <p>If there is a security manager, and this thread is not
|
|
1490 |
* the current thread, then the security manager's
|
|
1491 |
* <tt>checkPermission</tt> method is called with a
|
|
1492 |
* <tt>RuntimePermission("getStackTrace")</tt> permission
|
|
1493 |
* to see if it's ok to get the stack trace.
|
|
1494 |
*
|
|
1495 |
* <p>Some virtual machines may, under some circumstances, omit one
|
|
1496 |
* or more stack frames from the stack trace. In the extreme case,
|
|
1497 |
* a virtual machine that has no stack trace information concerning
|
|
1498 |
* this thread is permitted to return a zero-length array from this
|
|
1499 |
* method.
|
|
1500 |
*
|
|
1501 |
* @return an array of <tt>StackTraceElement</tt>,
|
|
1502 |
* each represents one stack frame.
|
|
1503 |
*
|
|
1504 |
* @throws SecurityException
|
|
1505 |
* if a security manager exists and its
|
|
1506 |
* <tt>checkPermission</tt> method doesn't allow
|
|
1507 |
* getting the stack trace of thread.
|
|
1508 |
* @see SecurityManager#checkPermission
|
|
1509 |
* @see RuntimePermission
|
|
1510 |
* @see Throwable#getStackTrace
|
|
1511 |
*
|
|
1512 |
* @since 1.5
|
|
1513 |
*/
|
|
1514 |
public StackTraceElement[] getStackTrace() {
|
|
1515 |
if (this != Thread.currentThread()) {
|
|
1516 |
// check for getStackTrace permission
|
|
1517 |
SecurityManager security = System.getSecurityManager();
|
|
1518 |
if (security != null) {
|
|
1519 |
security.checkPermission(
|
|
1520 |
SecurityConstants.GET_STACK_TRACE_PERMISSION);
|
|
1521 |
}
|
|
1522 |
// optimization so we do not call into the vm for threads that
|
|
1523 |
// have not yet started or have terminated
|
|
1524 |
if (!isAlive()) {
|
|
1525 |
return EMPTY_STACK_TRACE;
|
|
1526 |
}
|
|
1527 |
StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
|
|
1528 |
StackTraceElement[] stackTrace = stackTraceArray[0];
|
|
1529 |
// a thread that was alive during the previous isAlive call may have
|
|
1530 |
// since terminated, therefore not having a stacktrace.
|
|
1531 |
if (stackTrace == null) {
|
|
1532 |
stackTrace = EMPTY_STACK_TRACE;
|
|
1533 |
}
|
|
1534 |
return stackTrace;
|
|
1535 |
} else {
|
|
1536 |
// Don't need JVM help for current thread
|
|
1537 |
return (new Exception()).getStackTrace();
|
|
1538 |
}
|
|
1539 |
}
|
|
1540 |
|
|
1541 |
/**
|
|
1542 |
* Returns a map of stack traces for all live threads.
|
|
1543 |
* The map keys are threads and each map value is an array of
|
|
1544 |
* <tt>StackTraceElement</tt> that represents the stack dump
|
|
1545 |
* of the corresponding <tt>Thread</tt>.
|
|
1546 |
* The returned stack traces are in the format specified for
|
|
1547 |
* the {@link #getStackTrace getStackTrace} method.
|
|
1548 |
*
|
|
1549 |
* <p>The threads may be executing while this method is called.
|
|
1550 |
* The stack trace of each thread only represents a snapshot and
|
|
1551 |
* each stack trace may be obtained at different time. A zero-length
|
|
1552 |
* array will be returned in the map value if the virtual machine has
|
|
1553 |
* no stack trace information about a thread.
|
|
1554 |
*
|
|
1555 |
* <p>If there is a security manager, then the security manager's
|
|
1556 |
* <tt>checkPermission</tt> method is called with a
|
|
1557 |
* <tt>RuntimePermission("getStackTrace")</tt> permission as well as
|
|
1558 |
* <tt>RuntimePermission("modifyThreadGroup")</tt> permission
|
|
1559 |
* to see if it is ok to get the stack trace of all threads.
|
|
1560 |
*
|
|
1561 |
* @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
|
|
1562 |
* <tt>StackTraceElement</tt> that represents the stack trace of
|
|
1563 |
* the corresponding thread.
|
|
1564 |
*
|
|
1565 |
* @throws SecurityException
|
|
1566 |
* if a security manager exists and its
|
|
1567 |
* <tt>checkPermission</tt> method doesn't allow
|
|
1568 |
* getting the stack trace of thread.
|
|
1569 |
* @see #getStackTrace
|
|
1570 |
* @see SecurityManager#checkPermission
|
|
1571 |
* @see RuntimePermission
|
|
1572 |
* @see Throwable#getStackTrace
|
|
1573 |
*
|
|
1574 |
* @since 1.5
|
|
1575 |
*/
|
|
1576 |
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
|
|
1577 |
// check for getStackTrace permission
|
|
1578 |
SecurityManager security = System.getSecurityManager();
|
|
1579 |
if (security != null) {
|
|
1580 |
security.checkPermission(
|
|
1581 |
SecurityConstants.GET_STACK_TRACE_PERMISSION);
|
|
1582 |
security.checkPermission(
|
|
1583 |
SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
|
|
1584 |
}
|
|
1585 |
|
|
1586 |
// Get a snapshot of the list of all threads
|
|
1587 |
Thread[] threads = getThreads();
|
|
1588 |
StackTraceElement[][] traces = dumpThreads(threads);
|
|
1589 |
Map<Thread, StackTraceElement[]> m
|
|
1590 |
= new HashMap<Thread, StackTraceElement[]>(threads.length);
|
|
1591 |
for (int i = 0; i < threads.length; i++) {
|
|
1592 |
StackTraceElement[] stackTrace = traces[i];
|
|
1593 |
if (stackTrace != null) {
|
|
1594 |
m.put(threads[i], stackTrace);
|
|
1595 |
}
|
|
1596 |
// else terminated so we don't put it in the map
|
|
1597 |
}
|
|
1598 |
return m;
|
|
1599 |
}
|
|
1600 |
|
|
1601 |
|
|
1602 |
private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
|
|
1603 |
new RuntimePermission("enableContextClassLoaderOverride");
|
|
1604 |
|
|
1605 |
/** cache of subclass security audit results */
|
|
1606 |
private static final SoftCache subclassAudits = new SoftCache(10);
|
|
1607 |
|
|
1608 |
|
|
1609 |
/**
|
|
1610 |
* Verifies that this (possibly subclass) instance can be constructed
|
|
1611 |
* without violating security constraints: the subclass must not override
|
|
1612 |
* security-sensitive non-final methods, or else the
|
|
1613 |
* "enableContextClassLoaderOverride" RuntimePermission is checked.
|
|
1614 |
*/
|
|
1615 |
private static boolean isCCLOverridden(Class cl) {
|
|
1616 |
if (cl == Thread.class)
|
|
1617 |
return false;
|
|
1618 |
Boolean result = null;
|
|
1619 |
synchronized (subclassAudits) {
|
|
1620 |
result = (Boolean) subclassAudits.get(cl);
|
|
1621 |
if (result == null) {
|
|
1622 |
/*
|
|
1623 |
* Note: only new Boolean instances (i.e., not Boolean.TRUE or
|
|
1624 |
* Boolean.FALSE) must be used as cache values, otherwise cache
|
|
1625 |
* entry will pin associated class.
|
|
1626 |
*/
|
|
1627 |
result = new Boolean(auditSubclass(cl));
|
|
1628 |
subclassAudits.put(cl, result);
|
|
1629 |
}
|
|
1630 |
}
|
|
1631 |
return result.booleanValue();
|
|
1632 |
}
|
|
1633 |
|
|
1634 |
/**
|
|
1635 |
* Performs reflective checks on given subclass to verify that it doesn't
|
|
1636 |
* override security-sensitive non-final methods. Returns true if the
|
|
1637 |
* subclass overrides any of the methods, false otherwise.
|
|
1638 |
*/
|
|
1639 |
private static boolean auditSubclass(final Class subcl) {
|
|
1640 |
Boolean result = AccessController.doPrivileged(
|
|
1641 |
new PrivilegedAction<Boolean>() {
|
|
1642 |
public Boolean run() {
|
|
1643 |
for (Class cl = subcl;
|
|
1644 |
cl != Thread.class;
|
|
1645 |
cl = cl.getSuperclass())
|
|
1646 |
{
|
|
1647 |
try {
|
|
1648 |
cl.getDeclaredMethod("getContextClassLoader", new Class[0]);
|
|
1649 |
return Boolean.TRUE;
|
|
1650 |
} catch (NoSuchMethodException ex) {
|
|
1651 |
}
|
|
1652 |
try {
|
|
1653 |
Class[] params = {ClassLoader.class};
|
|
1654 |
cl.getDeclaredMethod("setContextClassLoader", params);
|
|
1655 |
return Boolean.TRUE;
|
|
1656 |
} catch (NoSuchMethodException ex) {
|
|
1657 |
}
|
|
1658 |
}
|
|
1659 |
return Boolean.FALSE;
|
|
1660 |
}
|
|
1661 |
}
|
|
1662 |
);
|
|
1663 |
return result.booleanValue();
|
|
1664 |
}
|
|
1665 |
|
|
1666 |
private native static StackTraceElement[][] dumpThreads(Thread[] threads);
|
|
1667 |
private native static Thread[] getThreads();
|
|
1668 |
|
|
1669 |
/**
|
|
1670 |
* Returns the identifier of this Thread. The thread ID is a positive
|
|
1671 |
* <tt>long</tt> number generated when this thread was created.
|
|
1672 |
* The thread ID is unique and remains unchanged during its lifetime.
|
|
1673 |
* When a thread is terminated, this thread ID may be reused.
|
|
1674 |
*
|
|
1675 |
* @return this thread's ID.
|
|
1676 |
* @since 1.5
|
|
1677 |
*/
|
|
1678 |
public long getId() {
|
|
1679 |
return tid;
|
|
1680 |
}
|
|
1681 |
|
|
1682 |
/**
|
|
1683 |
* A thread state. A thread can be in one of the following states:
|
|
1684 |
* <ul>
|
|
1685 |
* <li>{@link #NEW}<br>
|
|
1686 |
* A thread that has not yet started is in this state.
|
|
1687 |
* </li>
|
|
1688 |
* <li>{@link #RUNNABLE}<br>
|
|
1689 |
* A thread executing in the Java virtual machine is in this state.
|
|
1690 |
* </li>
|
|
1691 |
* <li>{@link #BLOCKED}<br>
|
|
1692 |
* A thread that is blocked waiting for a monitor lock
|
|
1693 |
* is in this state.
|
|
1694 |
* </li>
|
|
1695 |
* <li>{@link #WAITING}<br>
|
|
1696 |
* A thread that is waiting indefinitely for another thread to
|
|
1697 |
* perform a particular action is in this state.
|
|
1698 |
* </li>
|
|
1699 |
* <li>{@link #TIMED_WAITING}<br>
|
|
1700 |
* A thread that is waiting for another thread to perform an action
|
|
1701 |
* for up to a specified waiting time is in this state.
|
|
1702 |
* </li>
|
|
1703 |
* <li>{@link #TERMINATED}<br>
|
|
1704 |
* A thread that has exited is in this state.
|
|
1705 |
* </li>
|
|
1706 |
* </ul>
|
|
1707 |
*
|
|
1708 |
* <p>
|
|
1709 |
* A thread can be in only one state at a given point in time.
|
|
1710 |
* These states are virtual machine states which do not reflect
|
|
1711 |
* any operating system thread states.
|
|
1712 |
*
|
|
1713 |
* @since 1.5
|
|
1714 |
* @see #getState
|
|
1715 |
*/
|
|
1716 |
public enum State {
|
|
1717 |
/**
|
|
1718 |
* Thread state for a thread which has not yet started.
|
|
1719 |
*/
|
|
1720 |
NEW,
|
|
1721 |
|
|
1722 |
/**
|
|
1723 |
* Thread state for a runnable thread. A thread in the runnable
|
|
1724 |
* state is executing in the Java virtual machine but it may
|
|
1725 |
* be waiting for other resources from the operating system
|
|
1726 |
* such as processor.
|
|
1727 |
*/
|
|
1728 |
RUNNABLE,
|
|
1729 |
|
|
1730 |
/**
|
|
1731 |
* Thread state for a thread blocked waiting for a monitor lock.
|
|
1732 |
* A thread in the blocked state is waiting for a monitor lock
|
|
1733 |
* to enter a synchronized block/method or
|
|
1734 |
* reenter a synchronized block/method after calling
|
|
1735 |
* {@link Object#wait() Object.wait}.
|
|
1736 |
*/
|
|
1737 |
BLOCKED,
|
|
1738 |
|
|
1739 |
/**
|
|
1740 |
* Thread state for a waiting thread.
|
|
1741 |
* A thread is in the waiting state due to calling one of the
|
|
1742 |
* following methods:
|
|
1743 |
* <ul>
|
|
1744 |
* <li>{@link Object#wait() Object.wait} with no timeout</li>
|
|
1745 |
* <li>{@link #join() Thread.join} with no timeout</li>
|
|
1746 |
* <li>{@link LockSupport#park() LockSupport.park}</li>
|
|
1747 |
* </ul>
|
|
1748 |
*
|
|
1749 |
* <p>A thread in the waiting state is waiting for another thread to
|
|
1750 |
* perform a particular action.
|
|
1751 |
*
|
|
1752 |
* For example, a thread that has called <tt>Object.wait()</tt>
|
|
1753 |
* on an object is waiting for another thread to call
|
|
1754 |
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
|
|
1755 |
* that object. A thread that has called <tt>Thread.join()</tt>
|
|
1756 |
* is waiting for a specified thread to terminate.
|
|
1757 |
*/
|
|
1758 |
WAITING,
|
|
1759 |
|
|
1760 |
/**
|
|
1761 |
* Thread state for a waiting thread with a specified waiting time.
|
|
1762 |
* A thread is in the timed waiting state due to calling one of
|
|
1763 |
* the following methods with a specified positive waiting time:
|
|
1764 |
* <ul>
|
|
1765 |
* <li>{@link #sleep Thread.sleep}</li>
|
|
1766 |
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
|
|
1767 |
* <li>{@link #join(long) Thread.join} with timeout</li>
|
|
1768 |
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
|
|
1769 |
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
|
|
1770 |
* </ul>
|
|
1771 |
*/
|
|
1772 |
TIMED_WAITING,
|
|
1773 |
|
|
1774 |
/**
|
|
1775 |
* Thread state for a terminated thread.
|
|
1776 |
* The thread has completed execution.
|
|
1777 |
*/
|
|
1778 |
TERMINATED;
|
|
1779 |
}
|
|
1780 |
|
|
1781 |
/**
|
|
1782 |
* Returns the state of this thread.
|
|
1783 |
* This method is designed for use in monitoring of the system state,
|
|
1784 |
* not for synchronization control.
|
|
1785 |
*
|
|
1786 |
* @return this thread's state.
|
|
1787 |
* @since 1.5
|
|
1788 |
*/
|
|
1789 |
public State getState() {
|
|
1790 |
// get current thread state
|
|
1791 |
return sun.misc.VM.toThreadState(threadStatus);
|
|
1792 |
}
|
|
1793 |
|
|
1794 |
// Added in JSR-166
|
|
1795 |
|
|
1796 |
/**
|
|
1797 |
* Interface for handlers invoked when a <tt>Thread</tt> abruptly
|
|
1798 |
* terminates due to an uncaught exception.
|
|
1799 |
* <p>When a thread is about to terminate due to an uncaught exception
|
|
1800 |
* the Java Virtual Machine will query the thread for its
|
|
1801 |
* <tt>UncaughtExceptionHandler</tt> using
|
|
1802 |
* {@link #getUncaughtExceptionHandler} and will invoke the handler's
|
|
1803 |
* <tt>uncaughtException</tt> method, passing the thread and the
|
|
1804 |
* exception as arguments.
|
|
1805 |
* If a thread has not had its <tt>UncaughtExceptionHandler</tt>
|
|
1806 |
* explicitly set, then its <tt>ThreadGroup</tt> object acts as its
|
|
1807 |
* <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
|
|
1808 |
* has no
|
|
1809 |
* special requirements for dealing with the exception, it can forward
|
|
1810 |
* the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
|
|
1811 |
* default uncaught exception handler}.
|
|
1812 |
*
|
|
1813 |
* @see #setDefaultUncaughtExceptionHandler
|
|
1814 |
* @see #setUncaughtExceptionHandler
|
|
1815 |
* @see ThreadGroup#uncaughtException
|
|
1816 |
* @since 1.5
|
|
1817 |
*/
|
|
1818 |
public interface UncaughtExceptionHandler {
|
|
1819 |
/**
|
|
1820 |
* Method invoked when the given thread terminates due to the
|
|
1821 |
* given uncaught exception.
|
|
1822 |
* <p>Any exception thrown by this method will be ignored by the
|
|
1823 |
* Java Virtual Machine.
|
|
1824 |
* @param t the thread
|
|
1825 |
* @param e the exception
|
|
1826 |
*/
|
|
1827 |
void uncaughtException(Thread t, Throwable e);
|
|
1828 |
}
|
|
1829 |
|
|
1830 |
// null unless explicitly set
|
|
1831 |
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
|
|
1832 |
|
|
1833 |
// null unless explicitly set
|
|
1834 |
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
|
|
1835 |
|
|
1836 |
/**
|
|
1837 |
* Set the default handler invoked when a thread abruptly terminates
|
|
1838 |
* due to an uncaught exception, and no other handler has been defined
|
|
1839 |
* for that thread.
|
|
1840 |
*
|
|
1841 |
* <p>Uncaught exception handling is controlled first by the thread, then
|
|
1842 |
* by the thread's {@link ThreadGroup} object and finally by the default
|
|
1843 |
* uncaught exception handler. If the thread does not have an explicit
|
|
1844 |
* uncaught exception handler set, and the thread's thread group
|
|
1845 |
* (including parent thread groups) does not specialize its
|
|
1846 |
* <tt>uncaughtException</tt> method, then the default handler's
|
|
1847 |
* <tt>uncaughtException</tt> method will be invoked.
|
|
1848 |
* <p>By setting the default uncaught exception handler, an application
|
|
1849 |
* can change the way in which uncaught exceptions are handled (such as
|
|
1850 |
* logging to a specific device, or file) for those threads that would
|
|
1851 |
* already accept whatever "default" behavior the system
|
|
1852 |
* provided.
|
|
1853 |
*
|
|
1854 |
* <p>Note that the default uncaught exception handler should not usually
|
|
1855 |
* defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
|
|
1856 |
* infinite recursion.
|
|
1857 |
*
|
|
1858 |
* @param eh the object to use as the default uncaught exception handler.
|
|
1859 |
* If <tt>null</tt> then there is no default handler.
|
|
1860 |
*
|
|
1861 |
* @throws SecurityException if a security manager is present and it
|
|
1862 |
* denies <tt>{@link RuntimePermission}
|
|
1863 |
* ("setDefaultUncaughtExceptionHandler")</tt>
|
|
1864 |
*
|
|
1865 |
* @see #setUncaughtExceptionHandler
|
|
1866 |
* @see #getUncaughtExceptionHandler
|
|
1867 |
* @see ThreadGroup#uncaughtException
|
|
1868 |
* @since 1.5
|
|
1869 |
*/
|
|
1870 |
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
|
|
1871 |
SecurityManager sm = System.getSecurityManager();
|
|
1872 |
if (sm != null) {
|
|
1873 |
sm.checkPermission(
|
|
1874 |
new RuntimePermission("setDefaultUncaughtExceptionHandler")
|
|
1875 |
);
|
|
1876 |
}
|
|
1877 |
|
|
1878 |
defaultUncaughtExceptionHandler = eh;
|
|
1879 |
}
|
|
1880 |
|
|
1881 |
/**
|
|
1882 |
* Returns the default handler invoked when a thread abruptly terminates
|
|
1883 |
* due to an uncaught exception. If the returned value is <tt>null</tt>,
|
|
1884 |
* there is no default.
|
|
1885 |
* @since 1.5
|
|
1886 |
* @see #setDefaultUncaughtExceptionHandler
|
|
1887 |
*/
|
|
1888 |
public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
|
|
1889 |
return defaultUncaughtExceptionHandler;
|
|
1890 |
}
|
|
1891 |
|
|
1892 |
/**
|
|
1893 |
* Returns the handler invoked when this thread abruptly terminates
|
|
1894 |
* due to an uncaught exception. If this thread has not had an
|
|
1895 |
* uncaught exception handler explicitly set then this thread's
|
|
1896 |
* <tt>ThreadGroup</tt> object is returned, unless this thread
|
|
1897 |
* has terminated, in which case <tt>null</tt> is returned.
|
|
1898 |
* @since 1.5
|
|
1899 |
*/
|
|
1900 |
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
|
|
1901 |
return uncaughtExceptionHandler != null ?
|
|
1902 |
uncaughtExceptionHandler : group;
|
|
1903 |
}
|
|
1904 |
|
|
1905 |
/**
|
|
1906 |
* Set the handler invoked when this thread abruptly terminates
|
|
1907 |
* due to an uncaught exception.
|
|
1908 |
* <p>A thread can take full control of how it responds to uncaught
|
|
1909 |
* exceptions by having its uncaught exception handler explicitly set.
|
|
1910 |
* If no such handler is set then the thread's <tt>ThreadGroup</tt>
|
|
1911 |
* object acts as its handler.
|
|
1912 |
* @param eh the object to use as this thread's uncaught exception
|
|
1913 |
* handler. If <tt>null</tt> then this thread has no explicit handler.
|
|
1914 |
* @throws SecurityException if the current thread is not allowed to
|
|
1915 |
* modify this thread.
|
|
1916 |
* @see #setDefaultUncaughtExceptionHandler
|
|
1917 |
* @see ThreadGroup#uncaughtException
|
|
1918 |
* @since 1.5
|
|
1919 |
*/
|
|
1920 |
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
|
|
1921 |
checkAccess();
|
|
1922 |
uncaughtExceptionHandler = eh;
|
|
1923 |
}
|
|
1924 |
|
|
1925 |
/**
|
|
1926 |
* Dispatch an uncaught exception to the handler. This method is
|
|
1927 |
* intended to be called only by the JVM.
|
|
1928 |
*/
|
|
1929 |
private void dispatchUncaughtException(Throwable e) {
|
|
1930 |
getUncaughtExceptionHandler().uncaughtException(this, e);
|
|
1931 |
}
|
|
1932 |
|
|
1933 |
/* Some private helper methods */
|
|
1934 |
private native void setPriority0(int newPriority);
|
|
1935 |
private native void stop0(Object o);
|
|
1936 |
private native void suspend0();
|
|
1937 |
private native void resume0();
|
|
1938 |
private native void interrupt0();
|
|
1939 |
}
|