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