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