1 |
/* |
2 |
* @(#)Thread.java 1.125 01/12/03 |
3 |
* |
4 |
* Copyright 2002 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.util.Map; |
13 |
import java.util.Collections; |
14 |
import sun.nio.ch.Interruptible; |
15 |
|
16 |
|
17 |
/** |
18 |
* <b>JSR166: Added UncaughtExceptionHandlers, removeAllThreadLocals</b>.<p> |
19 |
* A <i>thread</i> is a thread of execution in a program. The Java |
20 |
* Virtual Machine allows an application to have multiple threads of |
21 |
* execution running concurrently. |
22 |
* <p> |
23 |
* Every thread has a priority. Threads with higher priority are |
24 |
* executed in preference to threads with lower priority. Each thread |
25 |
* may or may not also be marked as a daemon. When code running in |
26 |
* some thread creates a new <code>Thread</code> object, the new |
27 |
* thread has its priority initially set equal to the priority of the |
28 |
* creating thread, and is a daemon thread if and only if the |
29 |
* creating thread is a daemon. |
30 |
* <p> |
31 |
* When a Java Virtual Machine starts up, there is usually a single |
32 |
* non-daemon thread (which typically calls the method named |
33 |
* <code>main</code> of some designated class). The Java Virtual |
34 |
* Machine continues to execute threads until either of the following |
35 |
* occurs: |
36 |
* <ul> |
37 |
* <li>The <code>exit</code> method of class <code>Runtime</code> has been |
38 |
* called and the security manager has permitted the exit operation |
39 |
* to take place. |
40 |
* <li>All threads that are not daemon threads have died, either by |
41 |
* returning from the call to the <code>run</code> method or by |
42 |
* throwing an exception that propagates beyond the <code>run</code> |
43 |
* method. |
44 |
* </ul> |
45 |
* <p> |
46 |
* There are two ways to create a new thread of execution. One is to |
47 |
* declare a class to be a subclass of <code>Thread</code>. This |
48 |
* subclass should override the <code>run</code> method of class |
49 |
* <code>Thread</code>. An instance of the subclass can then be |
50 |
* allocated and started. For example, a thread that computes primes |
51 |
* larger than a stated value could be written as follows: |
52 |
* <p><hr><blockquote><pre> |
53 |
* class PrimeThread extends Thread { |
54 |
* long minPrime; |
55 |
* PrimeThread(long minPrime) { |
56 |
* this.minPrime = minPrime; |
57 |
* } |
58 |
* |
59 |
* public void run() { |
60 |
* // compute primes larger than minPrime |
61 |
* . . . |
62 |
* } |
63 |
* } |
64 |
* </pre></blockquote><hr> |
65 |
* <p> |
66 |
* The following code would then create a thread and start it running: |
67 |
* <p><blockquote><pre> |
68 |
* PrimeThread p = new PrimeThread(143); |
69 |
* p.start(); |
70 |
* </pre></blockquote> |
71 |
* <p> |
72 |
* The other way to create a thread is to declare a class that |
73 |
* implements the <code>Runnable</code> interface. That class then |
74 |
* implements the <code>run</code> method. An instance of the class can |
75 |
* then be allocated, passed as an argument when creating |
76 |
* <code>Thread</code>, and started. The same example in this other |
77 |
* style looks like the following: |
78 |
* <p><hr><blockquote><pre> |
79 |
* class PrimeRun implements Runnable { |
80 |
* long minPrime; |
81 |
* PrimeRun(long minPrime) { |
82 |
* this.minPrime = minPrime; |
83 |
* } |
84 |
* |
85 |
* public void run() { |
86 |
* // compute primes larger than minPrime |
87 |
* . . . |
88 |
* } |
89 |
* } |
90 |
* </pre></blockquote><hr> |
91 |
* <p> |
92 |
* The following code would then create a thread and start it running: |
93 |
* <p><blockquote><pre> |
94 |
* PrimeRun p = new PrimeRun(143); |
95 |
* new Thread(p).start(); |
96 |
* </pre></blockquote> |
97 |
* <p> |
98 |
* Every thread has a name for identification purposes. More than |
99 |
* one thread may have the same name. If a name is not specified when |
100 |
* a thread is created, a new name is generated for it. |
101 |
* |
102 |
* @author unascribed |
103 |
* @version 1.125, 12/03/01 |
104 |
* @see java.lang.Runnable |
105 |
* @see java.lang.Runtime#exit(int) |
106 |
* @see java.lang.Thread#run() |
107 |
* @see java.lang.Thread#stop() |
108 |
* @since JDK1.0 |
109 |
*/ |
110 |
public |
111 |
class Thread implements Runnable { |
112 |
|
113 |
/** |
114 |
* Interface for handlers invoked when a Thread abruptly terminates |
115 |
* due to an uncaught exception. |
116 |
*/ |
117 |
public interface UncaughtExceptionHandler { // jsr166 |
118 |
void uncaughtException(Thread t, Throwable e); |
119 |
} |
120 |
|
121 |
private static UncaughtExceptionHandler defaultUncaughtExceptionHandler; // jsr166 |
122 |
|
123 |
/** |
124 |
* Set the default handler invoked when a Thread abruptly terminates |
125 |
* due to an uncaught exception. If unset or set to null, a |
126 |
* Thread's ThreadGroup serves as the default handler. |
127 |
* @exception SecurityException if the current thread is not allowed to |
128 |
* current thread. |
129 |
*/ |
130 |
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { // jsr166 |
131 |
currentThread().checkAccess(); |
132 |
defaultUncaughtExceptionHandler = eh; |
133 |
} |
134 |
|
135 |
|
136 |
/** |
137 |
* Return the default handler invoked when a Thread abruptly terminates |
138 |
* due to an uncaught exception. |
139 |
*/ |
140 |
public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { // jsr166 |
141 |
return defaultUncaughtExceptionHandler; |
142 |
} |
143 |
|
144 |
/** |
145 |
* Return the handler invoked when this Thread abruptly terminates |
146 |
* due to an uncaught exception. |
147 |
*/ |
148 |
public UncaughtExceptionHandler getUncaughtExceptionHandler() { // jsr166 |
149 |
return (uncaughtExceptionHandler != null)? |
150 |
uncaughtExceptionHandler : |
151 |
group; |
152 |
} |
153 |
|
154 |
|
155 |
/** |
156 |
* Set the handler invoked when this Thread abruptly terminates |
157 |
* due to an uncaught exception. |
158 |
* @exception SecurityException if the current thread is not allowed to |
159 |
* modify current thread. |
160 |
*/ |
161 |
public void setUncaughtExceptionHandler (UncaughtExceptionHandler eh) { // jsr166 |
162 |
checkAccess(); |
163 |
uncaughtExceptionHandler = eh; |
164 |
} |
165 |
|
166 |
/** |
167 |
* Remove all values associated with ThreadLocals and |
168 |
* InheritableThreadLocals for this thread. This method is |
169 |
* designed to be used only in Thread Pools and related contexts |
170 |
* in which a thread is reused to perform several unrelated tasks. |
171 |
* @exception SecurityException if the current thread is not allowed to |
172 |
* modify current thread. |
173 |
*/ |
174 |
public static void removeAllThreadLocals() { // jsr166 |
175 |
Thread t = currentThread(); |
176 |
t.checkAccess(); |
177 |
t.threadLocals = null; |
178 |
t.inheritableThreadLocals = null; |
179 |
} |
180 |
|
181 |
|
182 |
|
183 |
/* Make sure registerNatives is the first thing <clinit> does. */ |
184 |
private static native void registerNatives(); |
185 |
static { |
186 |
registerNatives(); |
187 |
} |
188 |
|
189 |
private char name[]; |
190 |
private int priority; |
191 |
private Thread threadQ; |
192 |
private long eetop; |
193 |
private UncaughtExceptionHandler uncaughtExceptionHandler; // jsr166 |
194 |
|
195 |
/* Whether or not to single_step this thread. */ |
196 |
private boolean single_step; |
197 |
|
198 |
/* Whether or not the thread is a daemon thread. */ |
199 |
private boolean daemon = false; |
200 |
|
201 |
/* Whether or not this thread was asked to exit before it runs.*/ |
202 |
private boolean stillborn = false; |
203 |
|
204 |
/* What will be run. */ |
205 |
private Runnable target; |
206 |
|
207 |
/* The group of this thread */ |
208 |
private ThreadGroup group; |
209 |
|
210 |
/* The context ClassLoader for this thread */ |
211 |
private ClassLoader contextClassLoader; |
212 |
|
213 |
/* The inherited AccessControlContext of this thread */ |
214 |
private AccessControlContext inheritedAccessControlContext; |
215 |
|
216 |
/* For autonumbering anonymous threads. */ |
217 |
private static int threadInitNumber; |
218 |
private static synchronized int nextThreadNum() { |
219 |
return threadInitNumber++; |
220 |
} |
221 |
|
222 |
// static permissions |
223 |
private static RuntimePermission stopThreadPermission; |
224 |
|
225 |
/* ThreadLocal values pertaining to this thread. This map is maintained |
226 |
* by the ThreadLocal class. */ |
227 |
ThreadLocal.ThreadLocalMap threadLocals = null; |
228 |
|
229 |
/* |
230 |
* InheritableThreadLocal values pertaining to this thread. This map is |
231 |
* maintained by the InheritableThreadLocal class. |
232 |
*/ |
233 |
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; |
234 |
|
235 |
/* |
236 |
* The requested stack size for this thread, or 0 if the creator did |
237 |
* not specify a stack size. It is up to the VM to do whatever it |
238 |
* likes with this number; some VMs will ignore it. |
239 |
*/ |
240 |
private long stackSize; |
241 |
|
242 |
/* The object in which this thread is blocked in an interruptible I/O |
243 |
* operation, if any. The blocker's interrupt method() should be invoked |
244 |
* before setting this thread's interrupt status. |
245 |
*/ |
246 |
private volatile Interruptible blocker; |
247 |
|
248 |
/* Set the blocker field; invoked via reflection magic from java.nio code |
249 |
*/ |
250 |
private void blockedOn(Interruptible b) { |
251 |
blocker = b; |
252 |
} |
253 |
|
254 |
/** |
255 |
* The minimum priority that a thread can have. |
256 |
*/ |
257 |
public final static int MIN_PRIORITY = 1; |
258 |
|
259 |
/** |
260 |
* The default priority that is assigned to a thread. |
261 |
*/ |
262 |
public final static int NORM_PRIORITY = 5; |
263 |
|
264 |
/** |
265 |
* The maximum priority that a thread can have. |
266 |
*/ |
267 |
public final static int MAX_PRIORITY = 10; |
268 |
|
269 |
/** |
270 |
* Returns a reference to the currently executing thread object. |
271 |
* |
272 |
* @return the currently executing thread. |
273 |
*/ |
274 |
public static native Thread currentThread(); |
275 |
|
276 |
/** |
277 |
* Causes the currently executing thread object to temporarily pause |
278 |
* and allow other threads to execute. |
279 |
*/ |
280 |
public static native void yield(); |
281 |
|
282 |
/** |
283 |
* Causes the currently executing thread to sleep (temporarily cease |
284 |
* execution) for the specified number of milliseconds. The thread |
285 |
* does not lose ownership of any monitors. |
286 |
* |
287 |
* @param millis the length of time to sleep in milliseconds. |
288 |
* @exception InterruptedException if another thread has interrupted |
289 |
* the current thread. The <i>interrupted status</i> of the |
290 |
* current thread is cleared when this exception is thrown. |
291 |
* @see java.lang.Object#notify() |
292 |
*/ |
293 |
public static native void sleep(long millis) throws InterruptedException; |
294 |
|
295 |
/** |
296 |
* Causes the currently executing thread to sleep (cease execution) |
297 |
* for the specified number of milliseconds plus the specified number |
298 |
* of nanoseconds. The thread does not lose ownership of any monitors. |
299 |
* |
300 |
* @param millis the length of time to sleep in milliseconds. |
301 |
* @param nanos 0-999999 additional nanoseconds to sleep. |
302 |
* @exception IllegalArgumentException if the value of millis is |
303 |
* negative or the value of nanos is not in the range |
304 |
* 0-999999. |
305 |
* @exception InterruptedException if another thread has interrupted |
306 |
* the current thread. The <i>interrupted status</i> of the |
307 |
* current thread is cleared when this exception is thrown. |
308 |
* @see java.lang.Object#notify() |
309 |
*/ |
310 |
public static void sleep(long millis, int nanos) |
311 |
throws InterruptedException { |
312 |
if (millis < 0) { |
313 |
throw new IllegalArgumentException("timeout value is negative"); |
314 |
} |
315 |
|
316 |
if (nanos < 0 || nanos > 999999) { |
317 |
throw new IllegalArgumentException( |
318 |
"nanosecond timeout value out of range"); |
319 |
} |
320 |
|
321 |
if (nanos >= 500000 || (nanos != 0 && millis == 0)) { |
322 |
millis++; |
323 |
} |
324 |
|
325 |
sleep(millis); |
326 |
} |
327 |
|
328 |
/** |
329 |
* Initialize a Thread. |
330 |
* |
331 |
* @param g the Thread group |
332 |
* @param target the object whose run() method gets called |
333 |
* @param name the name of the new Thread |
334 |
* @param stackSize the desired stack size for the new thread, or |
335 |
* zero to indicate that this parameter is to be ignored. |
336 |
*/ |
337 |
private void init(ThreadGroup g, Runnable target, String name, |
338 |
long stackSize) { |
339 |
Thread parent = currentThread(); |
340 |
if (g == null) { |
341 |
/* Determine if it's an applet or not */ |
342 |
SecurityManager security = System.getSecurityManager(); |
343 |
|
344 |
/* If there is a security manager, ask the security manager |
345 |
what to do. */ |
346 |
if (security != null) { |
347 |
g = security.getThreadGroup(); |
348 |
} |
349 |
|
350 |
/* If the security doesn't have a strong opinion of the matter |
351 |
use the parent thread group. */ |
352 |
if (g == null) { |
353 |
g = parent.getThreadGroup(); |
354 |
} |
355 |
} |
356 |
|
357 |
/* checkAccess regardless of whether or not threadgroup is |
358 |
explicitly passed in. */ |
359 |
g.checkAccess(); |
360 |
|
361 |
this.group = g; |
362 |
this.daemon = parent.isDaemon(); |
363 |
this.priority = parent.getPriority(); |
364 |
this.name = name.toCharArray(); |
365 |
this.contextClassLoader = parent.contextClassLoader; |
366 |
this.inheritedAccessControlContext = AccessController.getContext(); |
367 |
this.target = target; |
368 |
setPriority(priority); |
369 |
if (parent.inheritableThreadLocals != null) |
370 |
this.inheritableThreadLocals = |
371 |
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); |
372 |
|
373 |
/* Stash the specified stack size in case the VM cares */ |
374 |
this.stackSize = stackSize; |
375 |
|
376 |
g.add(this); |
377 |
} |
378 |
|
379 |
/** |
380 |
* Allocates a new <code>Thread</code> object. This constructor has |
381 |
* the same effect as <code>Thread(null, null,</code> |
382 |
* <i>gname</i><code>)</code>, where <b><i>gname</i></b> is |
383 |
* a newly generated name. Automatically generated names are of the |
384 |
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. |
385 |
* |
386 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
387 |
* java.lang.Runnable, java.lang.String) |
388 |
*/ |
389 |
public Thread() { |
390 |
init(null, null, "Thread-" + nextThreadNum(), 0); |
391 |
} |
392 |
|
393 |
/** |
394 |
* Allocates a new <code>Thread</code> object. This constructor has |
395 |
* the same effect as <code>Thread(null, target,</code> |
396 |
* <i>gname</i><code>)</code>, where <i>gname</i> is |
397 |
* a newly generated name. Automatically generated names are of the |
398 |
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. |
399 |
* |
400 |
* @param target the object whose <code>run</code> method is called. |
401 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
402 |
* java.lang.Runnable, java.lang.String) |
403 |
*/ |
404 |
public Thread(Runnable target) { |
405 |
init(null, target, "Thread-" + nextThreadNum(), 0); |
406 |
} |
407 |
|
408 |
/** |
409 |
* Allocates a new <code>Thread</code> object. This constructor has |
410 |
* the same effect as <code>Thread(group, target,</code> |
411 |
* <i>gname</i><code>)</code>, where <i>gname</i> is |
412 |
* a newly generated name. Automatically generated names are of the |
413 |
* form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. |
414 |
* |
415 |
* @param group the thread group. |
416 |
* @param target the object whose <code>run</code> method is called. |
417 |
* @exception SecurityException if the current thread cannot create a |
418 |
* thread in the specified thread group. |
419 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
420 |
* java.lang.Runnable, java.lang.String) |
421 |
*/ |
422 |
public Thread(ThreadGroup group, Runnable target) { |
423 |
init(group, target, "Thread-" + nextThreadNum(), 0); |
424 |
} |
425 |
|
426 |
/** |
427 |
* Allocates a new <code>Thread</code> object. This constructor has |
428 |
* the same effect as <code>Thread(null, null, name)</code>. |
429 |
* |
430 |
* @param name the name of the new thread. |
431 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
432 |
* java.lang.Runnable, java.lang.String) |
433 |
*/ |
434 |
public Thread(String name) { |
435 |
init(null, null, name, 0); |
436 |
} |
437 |
|
438 |
/** |
439 |
* Allocates a new <code>Thread</code> object. This constructor has |
440 |
* the same effect as <code>Thread(group, null, name)</code> |
441 |
* |
442 |
* @param group the thread group. |
443 |
* @param name the name of the new thread. |
444 |
* @exception SecurityException if the current thread cannot create a |
445 |
* thread in the specified thread group. |
446 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
447 |
* java.lang.Runnable, java.lang.String) |
448 |
*/ |
449 |
public Thread(ThreadGroup group, String name) { |
450 |
init(group, null, name, 0); |
451 |
} |
452 |
|
453 |
/** |
454 |
* Allocates a new <code>Thread</code> object. This constructor has |
455 |
* the same effect as <code>Thread(null, target, name)</code>. |
456 |
* |
457 |
* @param target the object whose <code>run</code> method is called. |
458 |
* @param name the name of the new thread. |
459 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
460 |
* java.lang.Runnable, java.lang.String) |
461 |
*/ |
462 |
public Thread(Runnable target, String name) { |
463 |
init(null, target, name, 0); |
464 |
} |
465 |
|
466 |
/** |
467 |
* Allocates a new <code>Thread</code> object so that it has |
468 |
* <code>target</code> as its run object, has the specified |
469 |
* <code>name</code> as its name, and belongs to the thread group |
470 |
* referred to by <code>group</code>. |
471 |
* <p> |
472 |
* If <code>group</code> is <code>null</code> and there is a |
473 |
* security manager, the group is determined by the security manager's |
474 |
* <code>getThreadGroup</code> method. If <code>group</code> is |
475 |
* <code>null</code> and there is not a security manager, or the |
476 |
* security manager's <code>getThreadGroup</code> method returns |
477 |
* <code>null</code>, the group is set to be the same ThreadGroup |
478 |
* as the thread that is creating the new thread. |
479 |
* |
480 |
* <p>If there is a security manager, its <code>checkAccess</code> |
481 |
* method is called with the ThreadGroup as its argument. |
482 |
* This may result in a SecurityException. |
483 |
* <p> |
484 |
* If the <code>target</code> argument is not <code>null</code>, the |
485 |
* <code>run</code> method of the <code>target</code> is called when |
486 |
* this thread is started. If the target argument is |
487 |
* <code>null</code>, this thread's <code>run</code> method is called |
488 |
* when this thread is started. |
489 |
* <p> |
490 |
* The priority of the newly created thread is set equal to the |
491 |
* priority of the thread creating it, that is, the currently running |
492 |
* thread. The method <code>setPriority</code> may be used to |
493 |
* change the priority to a new value. |
494 |
* <p> |
495 |
* The newly created thread is initially marked as being a daemon |
496 |
* thread if and only if the thread creating it is currently marked |
497 |
* as a daemon thread. The method <code>setDaemon </code> may be used |
498 |
* to change whether or not a thread is a daemon. |
499 |
* |
500 |
* @param group the thread group. |
501 |
* @param target the object whose <code>run</code> method is called. |
502 |
* @param name the name of the new thread. |
503 |
* @exception SecurityException if the current thread cannot create a |
504 |
* thread in the specified thread group. |
505 |
* @see java.lang.Runnable#run() |
506 |
* @see java.lang.Thread#run() |
507 |
* @see java.lang.Thread#setDaemon(boolean) |
508 |
* @see java.lang.Thread#setPriority(int) |
509 |
* @see java.lang.ThreadGroup#checkAccess() |
510 |
* @see SecurityManager#checkAccess |
511 |
*/ |
512 |
public Thread(ThreadGroup group, Runnable target, String name) { |
513 |
init(group, target, name, 0); |
514 |
} |
515 |
|
516 |
/** |
517 |
* Allocates a new <code>Thread</code> object so that it has |
518 |
* <code>target</code> as its run object, has the specified |
519 |
* <code>name</code> as its name, belongs to the thread group referred to |
520 |
* by <code>group</code>, and has the specified <i>stack size</i>. |
521 |
* |
522 |
* <p>This constructor is identical to {@link |
523 |
* #Thread(ThreadGroup,Runnable,String)} with the exception of the fact |
524 |
* that it allows the thread stack size to be specified. The stack size |
525 |
* is the approximate number of bytes of address space that the virtual |
526 |
* machine is to allocate for this thread's stack. <b>The effect of the |
527 |
* <tt>stackSize</tt> parameter, if any, is highly platform dependent.</b> |
528 |
* |
529 |
* <p>On some platforms, specifying a higher value for the |
530 |
* <tt>stackSize</tt> parameter may allow a thread to achieve greater |
531 |
* recursion depth before throwing a {@link StackOverflowError}. |
532 |
* Similarly, specifying a lower value may allow a greater number of |
533 |
* threads to exist concurrently without throwing an an {@link |
534 |
* OutOfMemoryError} (or other internal error). The details of |
535 |
* the relationship between the value of the <tt>stackSize</tt> parameter |
536 |
* and the maximum recursion depth and concurrency level are |
537 |
* platform-dependent. <b>On some platforms, the value of the |
538 |
* <tt>stackSize</tt> parameter may have no effect whatsoever.</b> |
539 |
* |
540 |
* <p>The virtual machine is free to treat the <tt>stackSize</tt> |
541 |
* parameter as a suggestion. If the specified value is unreasonably low |
542 |
* for the platform, the virtual machine may instead use some |
543 |
* platform-specific minimum value; if the specified value is unreasonably |
544 |
* high, the virtual machine may instead use some platform-specific |
545 |
* maximum. Likewise, the virtual machine is free to round the specified |
546 |
* value up or down as it sees fit (or to ignore it completely). |
547 |
* |
548 |
* <p>Specifying a value of zero for the <tt>stackSize</tt> parameter will |
549 |
* cause this constructor to behave exactly like the |
550 |
* <tt>Thread(ThreadGroup, Runnable, String)</tt> constructor. |
551 |
* |
552 |
* <p><i>Due to the platform-dependent nature of the behavior of this |
553 |
* constructor, extreme care should be exercised in its use. |
554 |
* The thread stack size necessary to perform a given computation will |
555 |
* likely vary from one JRE implementation to another. In light of this |
556 |
* variation, careful tuning of the stack size parameter may be required, |
557 |
* and the tuning may need to be repeated for each JRE implementation on |
558 |
* which an application is to run.</i> |
559 |
* |
560 |
* <p>Implementation note: Java platform implementers are encouraged to |
561 |
* document their implementation's behavior with respect to the |
562 |
* <tt>stackSize parameter</tt>. |
563 |
* |
564 |
* @param group the thread group. |
565 |
* @param target the object whose <code>run</code> method is called. |
566 |
* @param name the name of the new thread. |
567 |
* @param stackSize the desired stack size for the new thread, or |
568 |
* zero to indicate that this parameter is to be ignored. |
569 |
* @exception SecurityException if the current thread cannot create a |
570 |
* thread in the specified thread group. |
571 |
*/ |
572 |
public Thread(ThreadGroup group, Runnable target, String name, |
573 |
long stackSize) { |
574 |
init(group, target, name, stackSize); |
575 |
} |
576 |
|
577 |
/** |
578 |
* Causes this thread to begin execution; the Java Virtual Machine |
579 |
* calls the <code>run</code> method of this thread. |
580 |
* <p> |
581 |
* The result is that two threads are running concurrently: the |
582 |
* current thread (which returns from the call to the |
583 |
* <code>start</code> method) and the other thread (which executes its |
584 |
* <code>run</code> method). |
585 |
* |
586 |
* @exception IllegalThreadStateException if the thread was already |
587 |
* started. |
588 |
* @see java.lang.Thread#run() |
589 |
* @see java.lang.Thread#stop() |
590 |
*/ |
591 |
public synchronized native void start(); |
592 |
|
593 |
/** |
594 |
* If this thread was constructed using a separate |
595 |
* <code>Runnable</code> run object, then that |
596 |
* <code>Runnable</code> object's <code>run</code> method is called; |
597 |
* otherwise, this method does nothing and returns. |
598 |
* <p> |
599 |
* Subclasses of <code>Thread</code> should override this method. |
600 |
* |
601 |
* @see java.lang.Thread#start() |
602 |
* @see java.lang.Thread#stop() |
603 |
* @see java.lang.Thread#Thread(java.lang.ThreadGroup, |
604 |
* java.lang.Runnable, java.lang.String) |
605 |
* @see java.lang.Runnable#run() |
606 |
*/ |
607 |
public void run() { |
608 |
if (target != null) { |
609 |
target.run(); |
610 |
} |
611 |
} |
612 |
|
613 |
/** |
614 |
* This method is called by the system to give a Thread |
615 |
* a chance to clean up before it actually exits. |
616 |
*/ |
617 |
private void exit() { |
618 |
if (group != null) { |
619 |
group.remove(this); |
620 |
group = null; |
621 |
} |
622 |
/* Aggressively null object connected to Thread: see bug 4006245 */ |
623 |
target = null; |
624 |
} |
625 |
|
626 |
/** |
627 |
* Forces the thread to stop executing. |
628 |
* <p> |
629 |
* If there is a security manager installed, its <code>checkAccess</code> |
630 |
* method is called with <code>this</code> |
631 |
* as its argument. This may result in a |
632 |
* <code>SecurityException</code> being raised (in the current thread). |
633 |
* <p> |
634 |
* If this thread is different from the current thread (that is, the current |
635 |
* thread is trying to stop a thread other than itself), the |
636 |
* security manager's <code>checkPermission</code> method (with a |
637 |
* <code>RuntimePermission("stopThread")</code> argument) is called in |
638 |
* addition. |
639 |
* Again, this may result in throwing a |
640 |
* <code>SecurityException</code> (in the current thread). |
641 |
* <p> |
642 |
* The thread represented by this thread is forced to stop whatever |
643 |
* it is doing abnormally and to throw a newly created |
644 |
* <code>ThreadDeath</code> object as an exception. |
645 |
* <p> |
646 |
* It is permitted to stop a thread that has not yet been started. |
647 |
* If the thread is eventually started, it immediately terminates. |
648 |
* <p> |
649 |
* An application should not normally try to catch |
650 |
* <code>ThreadDeath</code> unless it must do some extraordinary |
651 |
* cleanup operation (note that the throwing of |
652 |
* <code>ThreadDeath</code> causes <code>finally</code> clauses of |
653 |
* <code>try</code> statements to be executed before the thread |
654 |
* officially dies). If a <code>catch</code> clause catches a |
655 |
* <code>ThreadDeath</code> object, it is important to rethrow the |
656 |
* object so that the thread actually dies. |
657 |
* <p> |
658 |
* The top-level error handler that reacts to otherwise uncaught |
659 |
* exceptions does not print out a message or otherwise notify the |
660 |
* application if the uncaught exception is an instance of |
661 |
* <code>ThreadDeath</code>. |
662 |
* |
663 |
* @exception SecurityException if the current thread cannot |
664 |
* modify this thread. |
665 |
* @see java.lang.Thread#interrupt() |
666 |
* @see java.lang.Thread#checkAccess() |
667 |
* @see java.lang.Thread#run() |
668 |
* @see java.lang.Thread#start() |
669 |
* @see java.lang.ThreadDeath |
670 |
* @see java.lang.ThreadGroup#uncaughtException(java.lang.Thread, |
671 |
* java.lang.Throwable) |
672 |
* @see SecurityManager#checkAccess(Thread) |
673 |
* @see SecurityManager#checkPermission |
674 |
* @deprecated This method is inherently unsafe. Stopping a thread with |
675 |
* Thread.stop causes it to unlock all of the monitors that it |
676 |
* has locked (as a natural consequence of the unchecked |
677 |
* <code>ThreadDeath</code> exception propagating up the stack). If |
678 |
* any of the objects previously protected by these monitors were in |
679 |
* an inconsistent state, the damaged objects become visible to |
680 |
* other threads, potentially resulting in arbitrary behavior. Many |
681 |
* uses of <code>stop</code> should be replaced by code that simply |
682 |
* modifies some variable to indicate that the target thread should |
683 |
* stop running. The target thread should check this variable |
684 |
* regularly, and return from its run method in an orderly fashion |
685 |
* if the variable indicates that it is to stop running. If the |
686 |
* target thread waits for long periods (on a condition variable, |
687 |
* for example), the <code>interrupt</code> method should be used to |
688 |
* interrupt the wait. |
689 |
* For more information, see |
690 |
* <a href="{@docRoot}/../guide/misc/threadPrimitiveDeprecation.html">Why |
691 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. |
692 |
*/ |
693 |
public final void stop() { |
694 |
synchronized (this) { |
695 |
//if the thread is alreay dead, return |
696 |
if (!this.isAlive()) return; |
697 |
SecurityManager security = System.getSecurityManager(); |
698 |
if (security != null) { |
699 |
checkAccess(); |
700 |
if (this != Thread.currentThread()) { |
701 |
if (stopThreadPermission == null) |
702 |
stopThreadPermission = |
703 |
new RuntimePermission("stopThread"); |
704 |
security.checkPermission(stopThreadPermission); |
705 |
} |
706 |
} |
707 |
resume(); // Wake up thread if it was suspended; no-op otherwise |
708 |
stop0(new ThreadDeath()); |
709 |
} |
710 |
} |
711 |
|
712 |
/** |
713 |
* Forces the thread to stop executing. |
714 |
* <p> |
715 |
* If there is a security manager installed, the <code>checkAccess</code> |
716 |
* method of this thread is called, which may result in a |
717 |
* <code>SecurityException</code> being raised (in the current thread). |
718 |
* <p> |
719 |
* If this thread is different from the current thread (that is, the current |
720 |
* thread is trying to stop a thread other than itself) or |
721 |
* <code>obj</code> is not an instance of <code>ThreadDeath</code>, the |
722 |
* security manager's <code>checkPermission</code> method (with the |
723 |
* <code>RuntimePermission("stopThread")</code> argument) is called in |
724 |
* addition. |
725 |
* Again, this may result in throwing a |
726 |
* <code>SecurityException</code> (in the current thread). |
727 |
* <p> |
728 |
* If the argument <code>obj</code> is null, a |
729 |
* <code>NullPointerException</code> is thrown (in the current thread). |
730 |
* <p> |
731 |
* The thread represented by this thread is forced to complete |
732 |
* whatever it is doing abnormally and to throw the |
733 |
* <code>Throwable</code> object <code>obj</code> as an exception. This |
734 |
* is an unusual action to take; normally, the <code>stop</code> method |
735 |
* that takes no arguments should be used. |
736 |
* <p> |
737 |
* It is permitted to stop a thread that has not yet been started. |
738 |
* If the thread is eventually started, it immediately terminates. |
739 |
* |
740 |
* @param obj the Throwable object to be thrown. |
741 |
* @exception SecurityException if the current thread cannot modify |
742 |
* this thread. |
743 |
* @see java.lang.Thread#interrupt() |
744 |
* @see java.lang.Thread#checkAccess() |
745 |
* @see java.lang.Thread#run() |
746 |
* @see java.lang.Thread#start() |
747 |
* @see java.lang.Thread#stop() |
748 |
* @see SecurityManager#checkAccess(Thread) |
749 |
* @see SecurityManager#checkPermission |
750 |
* @deprecated This method is inherently unsafe. See {@link #stop} |
751 |
* (with no arguments) for details. An additional danger of this |
752 |
* method is that it may be used to generate exceptions that the |
753 |
* target thread is unprepared to handle (including checked |
754 |
* exceptions that the thread could not possibly throw, were it |
755 |
* not for this method). |
756 |
* For more information, see |
757 |
* <a href="{@docRoot}/../guide/misc/threadPrimitiveDeprecation.html">Why |
758 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. |
759 |
*/ |
760 |
public final synchronized void stop(Throwable obj) { |
761 |
SecurityManager security = System.getSecurityManager(); |
762 |
if (security != null) { |
763 |
checkAccess(); |
764 |
if ((this != Thread.currentThread()) || |
765 |
(!(obj instanceof ThreadDeath))) { |
766 |
if (stopThreadPermission == null) |
767 |
stopThreadPermission = new RuntimePermission("stopThread"); |
768 |
security.checkPermission(stopThreadPermission); |
769 |
} |
770 |
} |
771 |
resume(); // Wake up thread if it was suspended; no-op otherwise |
772 |
stop0(obj); |
773 |
} |
774 |
|
775 |
/** |
776 |
* Interrupts this thread. |
777 |
* |
778 |
* <p> First the {@link #checkAccess() checkAccess} method of this thread |
779 |
* is invoked, which may cause a {@link SecurityException} to be thrown. |
780 |
* |
781 |
* <p> If this thread is blocked in an invocation of the {@link |
782 |
* Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link |
783 |
* Object#wait(long, int) wait(long, int)} methods of the {@link Object} |
784 |
* class, or of the {@link #join()}, {@link #join(long)}, {@link |
785 |
* #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, |
786 |
* methods of this class, then its interrupt status will be cleared and it |
787 |
* will receive an {@link InterruptedException}. |
788 |
* |
789 |
* <p> If this thread is blocked in an I/O operation upon an {@link |
790 |
* java.nio.channels.InterruptibleChannel </code>interruptible |
791 |
* channel<code>} then the channel will be closed, the thread's interrupt |
792 |
* status will be set, and the thread will receive a {@link |
793 |
* java.nio.channels.ClosedByInterruptException}. |
794 |
* |
795 |
* <p> If this thread is blocked in a {@link java.nio.channels.Selector} |
796 |
* then the thread's interrupt status will be set and it will return |
797 |
* immediately from the selection operation, possibly with a non-zero |
798 |
* value, just as if the selector's {@link |
799 |
* java.nio.channels.Selector#wakeup wakeup} method were invoked. |
800 |
* |
801 |
* <p> If none of the previous conditions hold then this thread's interrupt |
802 |
* status will be set. </p> |
803 |
* |
804 |
* @throws SecurityException |
805 |
* if the current thread cannot modify this thread |
806 |
* |
807 |
* @revised 1.4 |
808 |
* @spec JSR-51 |
809 |
*/ |
810 |
public void interrupt() { |
811 |
checkAccess(); |
812 |
Interruptible b = blocker; |
813 |
if (b != null) { |
814 |
b.interrupt(); |
815 |
} |
816 |
interrupt0(); |
817 |
} |
818 |
|
819 |
/** |
820 |
* Tests whether the current thread has been interrupted. The |
821 |
* <i>interrupted status</i> of the thread is cleared by this method. In |
822 |
* other words, if this method were to be called twice in succession, the |
823 |
* second call would return false (unless the current thread were |
824 |
* interrupted again, after the first call had cleared its interrupted |
825 |
* status and before the second call had examined it). |
826 |
* |
827 |
* @return <code>true</code> if the current thread has been interrupted; |
828 |
* <code>false</code> otherwise. |
829 |
* @see java.lang.Thread#isInterrupted() |
830 |
*/ |
831 |
public static boolean interrupted() { |
832 |
return currentThread().isInterrupted(true); |
833 |
} |
834 |
|
835 |
/** |
836 |
* Tests whether this thread has been interrupted. The <i>interrupted |
837 |
* status</i> of the thread is unaffected by this method. |
838 |
* |
839 |
* @return <code>true</code> if this thread has been interrupted; |
840 |
* <code>false</code> otherwise. |
841 |
* @see java.lang.Thread#interrupted() |
842 |
*/ |
843 |
public boolean isInterrupted() { |
844 |
return isInterrupted(false); |
845 |
} |
846 |
|
847 |
/** |
848 |
* Tests if some Thread has been interrupted. The interrupted state |
849 |
* is reset or not based on the value of ClearInterrupted that is |
850 |
* passed. |
851 |
*/ |
852 |
private native boolean isInterrupted(boolean ClearInterrupted); |
853 |
|
854 |
/** |
855 |
* Destroys this thread, without any cleanup. Any monitors it has |
856 |
* locked remain locked. (This method is not implemented.) |
857 |
*/ |
858 |
public void destroy() { |
859 |
throw new NoSuchMethodError(); |
860 |
} |
861 |
|
862 |
/** |
863 |
* Tests if this thread is alive. A thread is alive if it has |
864 |
* been started and has not yet died. |
865 |
* |
866 |
* @return <code>true</code> if this thread is alive; |
867 |
* <code>false</code> otherwise. |
868 |
*/ |
869 |
public final native boolean isAlive(); |
870 |
|
871 |
/** |
872 |
* Suspends this thread. |
873 |
* <p> |
874 |
* First, the <code>checkAccess</code> method of this thread is called |
875 |
* with no arguments. This may result in throwing a |
876 |
* <code>SecurityException </code>(in the current thread). |
877 |
* <p> |
878 |
* If the thread is alive, it is suspended and makes no further |
879 |
* progress unless and until it is resumed. |
880 |
* |
881 |
* @exception SecurityException if the current thread cannot modify |
882 |
* this thread. |
883 |
* @see #checkAccess |
884 |
* @deprecated This method has been deprecated, as it is |
885 |
* inherently deadlock-prone. If the target thread holds a lock on the |
886 |
* monitor protecting a critical system resource when it is suspended, no |
887 |
* thread can access this resource until the target thread is resumed. If |
888 |
* the thread that would resume the target thread attempts to lock this |
889 |
* monitor prior to calling <code>resume</code>, deadlock results. Such |
890 |
* deadlocks typically manifest themselves as "frozen" processes. |
891 |
* For more information, see |
892 |
* <a href="{@docRoot}/../guide/misc/threadPrimitiveDeprecation.html">Why |
893 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. |
894 |
*/ |
895 |
public final void suspend() { |
896 |
checkAccess(); |
897 |
suspend0(); |
898 |
} |
899 |
|
900 |
/** |
901 |
* Resumes a suspended thread. |
902 |
* <p> |
903 |
* First, the <code>checkAccess</code> method of this thread is called |
904 |
* with no arguments. This may result in throwing a |
905 |
* <code>SecurityException</code> (in the current thread). |
906 |
* <p> |
907 |
* If the thread is alive but suspended, it is resumed and is |
908 |
* permitted to make progress in its execution. |
909 |
* |
910 |
* @exception SecurityException if the current thread cannot modify this |
911 |
* thread. |
912 |
* @see #checkAccess |
913 |
* @see java.lang.Thread#suspend() |
914 |
* @deprecated This method exists solely for use with {@link #suspend}, |
915 |
* which has been deprecated because it is deadlock-prone. |
916 |
* For more information, see |
917 |
* <a href="{@docRoot}/../guide/misc/threadPrimitiveDeprecation.html">Why |
918 |
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. |
919 |
*/ |
920 |
public final void resume() { |
921 |
checkAccess(); |
922 |
resume0(); |
923 |
} |
924 |
|
925 |
/** |
926 |
* Changes the priority of this thread. |
927 |
* <p> |
928 |
* First the <code>checkAccess</code> method of this thread is called |
929 |
* with no arguments. This may result in throwing a |
930 |
* <code>SecurityException</code>. |
931 |
* <p> |
932 |
* Otherwise, the priority of this thread is set to the smaller of |
933 |
* the specified <code>newPriority</code> and the maximum permitted |
934 |
* priority of the thread's thread group. |
935 |
* |
936 |
* @param newPriority priority to set this thread to |
937 |
* @exception IllegalArgumentException If the priority is not in the |
938 |
* range <code>MIN_PRIORITY</code> to |
939 |
* <code>MAX_PRIORITY</code>. |
940 |
* @exception SecurityException if the current thread cannot modify |
941 |
* this thread. |
942 |
* @see #getPriority |
943 |
* @see java.lang.Thread#checkAccess() |
944 |
* @see java.lang.Thread#getPriority() |
945 |
* @see java.lang.Thread#getThreadGroup() |
946 |
* @see java.lang.Thread#MAX_PRIORITY |
947 |
* @see java.lang.Thread#MIN_PRIORITY |
948 |
* @see java.lang.ThreadGroup#getMaxPriority() |
949 |
*/ |
950 |
public final void setPriority(int newPriority) { |
951 |
checkAccess(); |
952 |
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { |
953 |
throw new IllegalArgumentException(); |
954 |
} |
955 |
if (newPriority > group.getMaxPriority()) { |
956 |
newPriority = group.getMaxPriority(); |
957 |
} |
958 |
setPriority0(priority = newPriority); |
959 |
} |
960 |
|
961 |
/** |
962 |
* Returns this thread's priority. |
963 |
* |
964 |
* @return this thread's priority. |
965 |
* @see #setPriority |
966 |
* @see java.lang.Thread#setPriority(int) |
967 |
*/ |
968 |
public final int getPriority() { |
969 |
return priority; |
970 |
} |
971 |
|
972 |
/** |
973 |
* Changes the name of this thread to be equal to the argument |
974 |
* <code>name</code>. |
975 |
* <p> |
976 |
* First the <code>checkAccess</code> method of this thread is called |
977 |
* with no arguments. This may result in throwing a |
978 |
* <code>SecurityException</code>. |
979 |
* |
980 |
* @param name the new name for this thread. |
981 |
* @exception SecurityException if the current thread cannot modify this |
982 |
* thread. |
983 |
* @see #getName |
984 |
* @see java.lang.Thread#checkAccess() |
985 |
* @see java.lang.Thread#getName() |
986 |
*/ |
987 |
public final void setName(String name) { |
988 |
checkAccess(); |
989 |
this.name = name.toCharArray(); |
990 |
} |
991 |
|
992 |
/** |
993 |
* Returns this thread's name. |
994 |
* |
995 |
* @return this thread's name. |
996 |
* @see #setName |
997 |
* @see java.lang.Thread#setName(java.lang.String) |
998 |
*/ |
999 |
public final String getName() { |
1000 |
return String.valueOf(name); |
1001 |
} |
1002 |
|
1003 |
/** |
1004 |
* Returns the thread group to which this thread belongs. |
1005 |
* This method returns null if this thread has died |
1006 |
* (been stopped). |
1007 |
* |
1008 |
* @return this thread's thread group. |
1009 |
*/ |
1010 |
public final ThreadGroup getThreadGroup() { |
1011 |
return group; |
1012 |
} |
1013 |
|
1014 |
/** |
1015 |
* Returns the number of active threads in the current thread's thread |
1016 |
* group. |
1017 |
* |
1018 |
* @return the number of active threads in the current thread's thread |
1019 |
* group. |
1020 |
*/ |
1021 |
public static int activeCount() { |
1022 |
return currentThread().getThreadGroup().activeCount(); |
1023 |
} |
1024 |
|
1025 |
/** |
1026 |
* Copies into the specified array every active thread in |
1027 |
* the current thread's thread group and its subgroups. This method simply |
1028 |
* calls the <code>enumerate</code> method of the current thread's thread |
1029 |
* group with the array argument. |
1030 |
* <p> |
1031 |
* First, if there is a security manager, that <code>enumerate</code> |
1032 |
* method calls the security |
1033 |
* manager's <code>checkAccess</code> method |
1034 |
* with the thread group as its argument. This may result |
1035 |
* in throwing a <code>SecurityException</code>. |
1036 |
* |
1037 |
* @param tarray an array of Thread objects to copy to |
1038 |
* @return the number of threads put into the array |
1039 |
* @exception SecurityException if a security manager exists and its |
1040 |
* <code>checkAccess</code> method doesn't allow the operation. |
1041 |
* @see java.lang.ThreadGroup#enumerate(java.lang.Thread[]) |
1042 |
* @see java.lang.SecurityManager#checkAccess(java.lang.ThreadGroup) |
1043 |
*/ |
1044 |
public static int enumerate(Thread tarray[]) { |
1045 |
return currentThread().getThreadGroup().enumerate(tarray); |
1046 |
} |
1047 |
|
1048 |
/** |
1049 |
* Counts the number of stack frames in this thread. The thread must |
1050 |
* be suspended. |
1051 |
* |
1052 |
* @return the number of stack frames in this thread. |
1053 |
* @exception IllegalThreadStateException if this thread is not |
1054 |
* suspended. |
1055 |
* @deprecated The definition of this call depends on {@link #suspend}, |
1056 |
* which is deprecated. Further, the results of this call |
1057 |
* were never well-defined. |
1058 |
*/ |
1059 |
public native int countStackFrames(); |
1060 |
|
1061 |
/** |
1062 |
* Waits at most <code>millis</code> milliseconds for this thread to |
1063 |
* die. A timeout of <code>0</code> means to wait forever. |
1064 |
* |
1065 |
* @param millis the time to wait in milliseconds. |
1066 |
* @exception InterruptedException if another thread has interrupted |
1067 |
* the current thread. The <i>interrupted status</i> of the |
1068 |
* current thread is cleared when this exception is thrown. |
1069 |
*/ |
1070 |
public final synchronized void join(long millis) |
1071 |
throws InterruptedException { |
1072 |
long base = System.currentTimeMillis(); |
1073 |
long now = 0; |
1074 |
|
1075 |
if (millis < 0) { |
1076 |
throw new IllegalArgumentException("timeout value is negative"); |
1077 |
} |
1078 |
|
1079 |
if (millis == 0) { |
1080 |
while (isAlive()) { |
1081 |
wait(0); |
1082 |
} |
1083 |
} else { |
1084 |
while (isAlive()) { |
1085 |
long delay = millis - now; |
1086 |
if (delay <= 0) { |
1087 |
break; |
1088 |
} |
1089 |
wait(delay); |
1090 |
now = System.currentTimeMillis() - base; |
1091 |
} |
1092 |
} |
1093 |
} |
1094 |
|
1095 |
/** |
1096 |
* Waits at most <code>millis</code> milliseconds plus |
1097 |
* <code>nanos</code> nanoseconds for this thread to die. |
1098 |
* |
1099 |
* @param millis the time to wait in milliseconds. |
1100 |
* @param nanos 0-999999 additional nanoseconds to wait. |
1101 |
* @exception IllegalArgumentException if the value of millis is negative |
1102 |
* the value of nanos is not in the range 0-999999. |
1103 |
* @exception InterruptedException if another thread has interrupted |
1104 |
* the current thread. The <i>interrupted status</i> of the |
1105 |
* current thread is cleared when this exception is thrown. |
1106 |
*/ |
1107 |
public final synchronized void join(long millis, int nanos) |
1108 |
throws InterruptedException { |
1109 |
|
1110 |
if (millis < 0) { |
1111 |
throw new IllegalArgumentException("timeout value is negative"); |
1112 |
} |
1113 |
|
1114 |
if (nanos < 0 || nanos > 999999) { |
1115 |
throw new IllegalArgumentException( |
1116 |
"nanosecond timeout value out of range"); |
1117 |
} |
1118 |
|
1119 |
if (nanos >= 500000 || (nanos != 0 && millis == 0)) { |
1120 |
millis++; |
1121 |
} |
1122 |
|
1123 |
join(millis); |
1124 |
} |
1125 |
|
1126 |
/** |
1127 |
* Waits for this thread to die. |
1128 |
* |
1129 |
* @exception InterruptedException if another thread has interrupted |
1130 |
* the current thread. The <i>interrupted status</i> of the |
1131 |
* current thread is cleared when this exception is thrown. |
1132 |
*/ |
1133 |
public final void join() throws InterruptedException { |
1134 |
join(0); |
1135 |
} |
1136 |
|
1137 |
/** |
1138 |
* Prints a stack trace of the current thread. This method is used |
1139 |
* only for debugging. |
1140 |
* |
1141 |
* @see java.lang.Throwable#printStackTrace() |
1142 |
*/ |
1143 |
public static void dumpStack() { |
1144 |
new Exception("Stack trace").printStackTrace(); |
1145 |
} |
1146 |
|
1147 |
/** |
1148 |
* Marks this thread as either a daemon thread or a user thread. The |
1149 |
* Java Virtual Machine exits when the only threads running are all |
1150 |
* daemon threads. |
1151 |
* <p> |
1152 |
* This method must be called before the thread is started. |
1153 |
* <p> |
1154 |
* This method first calls the <code>checkAccess</code> method |
1155 |
* of this thread |
1156 |
* with no arguments. This may result in throwing a |
1157 |
* <code>SecurityException </code>(in the current thread). |
1158 |
* |
1159 |
* @param on if <code>true</code>, marks this thread as a |
1160 |
* daemon thread. |
1161 |
* @exception IllegalThreadStateException if this thread is active. |
1162 |
* @exception SecurityException if the current thread cannot modify |
1163 |
* this thread. |
1164 |
* @see java.lang.Thread#isDaemon() |
1165 |
* @see #checkAccess |
1166 |
*/ |
1167 |
public final void setDaemon(boolean on) { |
1168 |
checkAccess(); |
1169 |
if (isAlive()) { |
1170 |
throw new IllegalThreadStateException(); |
1171 |
} |
1172 |
daemon = on; |
1173 |
} |
1174 |
|
1175 |
/** |
1176 |
* Tests if this thread is a daemon thread. |
1177 |
* |
1178 |
* @return <code>true</code> if this thread is a daemon thread; |
1179 |
* <code>false</code> otherwise. |
1180 |
* @see java.lang.Thread#setDaemon(boolean) |
1181 |
*/ |
1182 |
public final boolean isDaemon() { |
1183 |
return daemon; |
1184 |
} |
1185 |
|
1186 |
/** |
1187 |
* Determines if the currently running thread has permission to |
1188 |
* modify this thread. |
1189 |
* <p> |
1190 |
* If there is a security manager, its <code>checkAccess</code> method |
1191 |
* is called with this thread as its argument. This may result in |
1192 |
* throwing a <code>SecurityException</code>. |
1193 |
* <p> |
1194 |
* Note: This method was mistakenly non-final in JDK 1.1. |
1195 |
* It has been made final in the Java 2 Platform. |
1196 |
* |
1197 |
* @exception SecurityException if the current thread is not allowed to |
1198 |
* access this thread. |
1199 |
* @see java.lang.SecurityManager#checkAccess(java.lang.Thread) |
1200 |
*/ |
1201 |
public final void checkAccess() { |
1202 |
SecurityManager security = System.getSecurityManager(); |
1203 |
if (security != null) { |
1204 |
security.checkAccess(this); |
1205 |
} |
1206 |
} |
1207 |
|
1208 |
/** |
1209 |
* Returns a string representation of this thread, including the |
1210 |
* thread's name, priority, and thread group. |
1211 |
* |
1212 |
* @return a string representation of this thread. |
1213 |
*/ |
1214 |
public String toString() { |
1215 |
ThreadGroup group = getThreadGroup(); |
1216 |
if (group != null) { |
1217 |
return "Thread[" + getName() + "," + getPriority() + "," + |
1218 |
group.getName() + "]"; |
1219 |
} else { |
1220 |
return "Thread[" + getName() + "," + getPriority() + "," + |
1221 |
"" + "]"; |
1222 |
} |
1223 |
} |
1224 |
|
1225 |
/** |
1226 |
* Returns the context ClassLoader for this Thread. The context |
1227 |
* ClassLoader is provided by the creator of the thread for use |
1228 |
* by code running in this thread when loading classes and resources. |
1229 |
* If not set, the default is the ClassLoader context of the parent |
1230 |
* Thread. The context ClassLoader of the primordial thread is |
1231 |
* typically set to the class loader used to load the application. |
1232 |
* |
1233 |
* <p>First, if there is a security manager, and the caller's class |
1234 |
* loader is not null and the caller's class loader is not the same as or |
1235 |
* an ancestor of the context class loader for the thread whose |
1236 |
* context class loader is being requested, then the security manager's |
1237 |
* <code>checkPermission</code> |
1238 |
* method is called with a |
1239 |
* <code>RuntimePermission("getClassLoader")</code> permission |
1240 |
* to see if it's ok to get the context ClassLoader.. |
1241 |
* |
1242 |
* @return the context ClassLoader for this Thread |
1243 |
* |
1244 |
* @throws SecurityException |
1245 |
* if a security manager exists and its |
1246 |
* <code>checkPermission</code> method doesn't allow |
1247 |
* getting the context ClassLoader. |
1248 |
* @see #setContextClassLoader |
1249 |
* @see SecurityManager#checkPermission |
1250 |
* @see java.lang.RuntimePermission |
1251 |
* |
1252 |
* @since 1.2 |
1253 |
*/ |
1254 |
public ClassLoader getContextClassLoader() { |
1255 |
if (contextClassLoader == null) |
1256 |
return null; |
1257 |
SecurityManager sm = System.getSecurityManager(); |
1258 |
if (sm != null) { |
1259 |
ClassLoader ccl = ClassLoader.getCallerClassLoader(); |
1260 |
if (ccl != null && ccl != contextClassLoader && |
1261 |
!contextClassLoader.isAncestor(ccl)) { |
1262 |
sm.checkPermission(ClassLoader.getGetClassLoaderPerm()); |
1263 |
} |
1264 |
} |
1265 |
return contextClassLoader; |
1266 |
} |
1267 |
|
1268 |
/** |
1269 |
* Sets the context ClassLoader for this Thread. The context |
1270 |
* ClassLoader can be set when a thread is created, and allows |
1271 |
* the creator of the thread to provide the appropriate class loader |
1272 |
* to code running in the thread when loading classes and resources. |
1273 |
* |
1274 |
* <p>First, if there is a security manager, its <code>checkPermission</code> |
1275 |
* method is called with a |
1276 |
* <code>RuntimePermission("setContextClassLoader")</code> permission |
1277 |
* to see if it's ok to set the context ClassLoader.. |
1278 |
* |
1279 |
* @param cl the context ClassLoader for this Thread |
1280 |
* |
1281 |
* @exception SecurityException if the current thread cannot set the |
1282 |
* context ClassLoader. |
1283 |
* @see #getContextClassLoader |
1284 |
* @see SecurityManager#checkPermission |
1285 |
* @see java.lang.RuntimePermission |
1286 |
* |
1287 |
* @since 1.2 |
1288 |
*/ |
1289 |
public void setContextClassLoader(ClassLoader cl) { |
1290 |
SecurityManager sm = System.getSecurityManager(); |
1291 |
if (sm != null) { |
1292 |
sm.checkPermission(new RuntimePermission("setContextClassLoader")); |
1293 |
} |
1294 |
contextClassLoader = cl; |
1295 |
} |
1296 |
|
1297 |
/** |
1298 |
* Returns <tt>true</tt> if and only if the current thread holds the |
1299 |
* monitor lock on the specified object. |
1300 |
* |
1301 |
* <p>This method is designed to allow a program to assert that |
1302 |
* the current thread already holds a specified lock: |
1303 |
* <pre> |
1304 |
* assert Thread.holdsLock(obj); |
1305 |
* </pre> |
1306 |
* |
1307 |
* @param obj the object on which to test lock ownership |
1308 |
* @throws NullPointerException if obj is <tt>null</tt> |
1309 |
* @return <tt>true</tt> if the current thread holds the monitor lock on |
1310 |
* the specified object. |
1311 |
* @since 1.4 |
1312 |
*/ |
1313 |
public static native boolean holdsLock(Object obj); |
1314 |
|
1315 |
/* Some private helper methods */ |
1316 |
private native void setPriority0(int newPriority); |
1317 |
private native void stop0(Object o); |
1318 |
private native void suspend0(); |
1319 |
private native void resume0(); |
1320 |
private native void interrupt0(); |
1321 |
} |