1 |
/* java.lang.Thread |
/* Thread -- an independent thread of executable code |
2 |
Copyright (C) 1998, 2001, 2002 Free Software Foundation |
Copyright (C) 1998, 2001, 2002 Free Software Foundation |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
38 |
package java.lang; |
package java.lang; |
39 |
|
|
40 |
/** |
/** |
41 |
** Thread represents a single thread of execution in the VM. |
* Thread represents a single thread of execution in the VM. When an |
42 |
** When an application VM starts up, it creates a new Thread |
* application VM starts up, it creates a non-daemon Thread which calls the |
43 |
** which calls the main() method of a particular class. There |
* main() method of a particular class. There may be other Threads running, |
44 |
** may be other Threads running, such as the garbage collection |
* such as the garbage collection thread. |
45 |
** thread.<P> |
* |
46 |
** |
* <p>Threads have names to identify them. These names are not necessarily |
47 |
** Threads have names to identify them. These names are not |
* unique. Every Thread has a priority, as well, which tells the VM which |
48 |
** necessarily unique.<P> |
* Threads should get more running time. New threads inherit the priority |
49 |
** |
* and daemon status of the parent thread, by default. |
50 |
** Every Thread has a priority, as well, which tells the VM |
* |
51 |
** which Threads get more running time.<P> |
* <p>There are two methods of creating a Thread: you may subclass Thread and |
52 |
** |
* implement the <code>run()</code> method, at which point you may start the |
53 |
** There are two methods of creating a Thread: you may |
* Thread by calling its <code>start()</code> method, or you may implement |
54 |
** subclass Thread and implement the <CODE>run()</CODE> method, at which |
* <code>Runnable</code> in the class you want to use and then call new |
55 |
** point you may start the Thread by calling its <CODE>start()</CODE> |
* <code>Thread(your_obj).start()</code>. |
56 |
** method, or you may implement <CODE>Runnable</CODE> in the class you |
* |
57 |
** want to use and then call new <CODE>Thread(your_obj).start()</CODE>. |
* <p>The virtual machine runs until all non-daemon threads have died (either |
58 |
** |
* by returning from the run() method as invoked by start(), or by throwing |
59 |
** @specnote it is unclear at what point a Thread should be added to a |
* an uncaught exception); or until <code>System.exit</code> is called with |
60 |
** ThreadGroup, and at what point it should be removed. |
* adequate permissions. |
61 |
** Should it be inserted when it starts, or when it is |
* |
62 |
** created? Should it be removed when it is suspended or |
* <p>It is unclear at what point a Thread should be added to a ThreadGroup, |
63 |
** interrupted? The only thing that is clear is that the |
* and at what point it should be removed. Should it be inserted when it |
64 |
** Thread should be removed when it is stopped. |
* starts, or when it is created? Should it be removed when it is suspended |
65 |
** @author John Keiser |
* or interrupted? The only thing that is clear is that the Thread should be |
66 |
** @version 1.1.0, Aug 6 1998 |
* removed when it is stopped. |
67 |
** @since JDK1.0 |
* |
68 |
**/ |
* @author John Keiser |
69 |
|
* @author Eric Blake <ebb9@email.byu.edu> |
70 |
public class Thread implements Runnable { |
* @see Runnable |
71 |
ThreadGroup group; |
* @see Runtime#exit(int) |
72 |
Runnable toRun; |
* @see #run() |
73 |
String name; |
* @see #start() |
74 |
boolean daemon; |
* @see ThreadLocal |
75 |
int priority; |
* @since 1.0 |
76 |
|
* @status updated to 1.4 |
77 |
/** The context classloader for this Thread. **/ |
*/ |
78 |
private ClassLoader contextClassLoader |
public class Thread implements Runnable |
79 |
= ClassLoader.getSystemClassLoader(); |
{ |
80 |
|
/** The minimum priority for a Thread. */ |
81 |
|
public static final int MIN_PRIORITY = 1; |
82 |
|
|
83 |
|
/** The priority a Thread gets by default. */ |
84 |
|
public static final int NORM_PRIORITY = 5; |
85 |
|
|
86 |
|
/** The maximum priority for a Thread. */ |
87 |
|
public static final int MAX_PRIORITY = 10; |
88 |
|
|
89 |
/** |
/** |
90 |
* The maximum priority for a Thread. |
* The group this thread belongs to. This is set to null by |
91 |
|
* ThreadGroup.removeThread when the thread dies. |
92 |
*/ |
*/ |
93 |
public static final int MAX_PRIORITY = 10; |
ThreadGroup group; |
94 |
|
|
95 |
|
/** The object to run(), null if this is the target. */ |
96 |
|
final Runnable toRun; |
97 |
|
|
98 |
|
/** The thread name, non-null. */ |
99 |
|
String name; |
100 |
|
|
101 |
|
/** Whether the thread is a daemon. */ |
102 |
|
boolean daemon; |
103 |
|
|
104 |
|
/** The thread priority, 1 to 10. */ |
105 |
|
int priority; |
106 |
|
|
107 |
|
/** The context classloader for this Thread. */ |
108 |
|
private ClassLoader contextClassLoader = ClassLoader.getSystemClassLoader(); |
109 |
|
|
110 |
|
/** The next thread number to use. */ |
111 |
|
private static int numAnonymousThreadsCreated = 0; |
112 |
|
|
113 |
/** |
/** |
114 |
* The priority a Thread gets by default. |
* Allocate a new Thread object, as if by |
115 |
|
* <code>Thread(null, null, <i>fake name</i>)</code>, where the fake name |
116 |
|
* is "Thread-" + <i>unique integer</i>. |
117 |
|
* |
118 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
119 |
*/ |
*/ |
120 |
public static final int NORM_PRIORITY = 5; |
public Thread() |
121 |
|
{ |
122 |
|
this(null, (Runnable) null); |
123 |
|
} |
124 |
|
|
125 |
|
/** |
126 |
|
* Allocate a new Thread object, as if by |
127 |
|
* <code>Thread(null, toRun, <i>fake name</i>)</code>, where the fake name |
128 |
|
* is "Thread-" + <i>unique integer</i>. |
129 |
|
* |
130 |
|
* @param toRun the Runnable object to execute |
131 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
132 |
|
*/ |
133 |
|
public Thread(Runnable toRun) |
134 |
|
{ |
135 |
|
this(null, toRun); |
136 |
|
} |
137 |
|
|
138 |
/** |
/** |
139 |
* The minimum priority for a Thread. |
* Allocate a new Thread object, as if by |
140 |
|
* <code>Thread(group, toRun, <i>fake name</i>)</code>, where the fake name |
141 |
|
* is "Thread-" + <i>unique integer</i>. |
142 |
|
* |
143 |
|
* @param group the group to put the Thread into |
144 |
|
* @param target the Runnable object to execute |
145 |
|
* @throws SecurityException if this thread cannot access <code>group</code> |
146 |
|
* @throws IllegalThreadStateException if group is destroyed |
147 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
148 |
*/ |
*/ |
149 |
public static final int MIN_PRIORITY = 1; |
public Thread(ThreadGroup group, Runnable toRun) |
150 |
|
{ |
151 |
|
this(group, toRun, "Thread-" + ++numAnonymousThreadsCreated, 0); |
152 |
|
} |
153 |
|
|
154 |
|
/** |
155 |
|
* Allocate a new Thread object, as if by |
156 |
|
* <code>Thread(null, null, name)</code>. |
157 |
|
* |
158 |
|
* @param name the name for the Thread |
159 |
|
* @throws NullPointerException if name is null |
160 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
161 |
|
*/ |
162 |
|
public Thread(String name) |
163 |
|
{ |
164 |
|
this(null, null, name, 0); |
165 |
|
} |
166 |
|
|
167 |
|
/** |
168 |
|
* Allocate a new Thread object, as if by |
169 |
|
* <code>Thread(group, null, name)</code>. |
170 |
|
* |
171 |
|
* @param group the group to put the Thread into |
172 |
|
* @param name the name for the Thread |
173 |
|
* @throws NullPointerException if name is null |
174 |
|
* @throws SecurityException if this thread cannot access <code>group</code> |
175 |
|
* @throws IllegalThreadStateException if group is destroyed |
176 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
177 |
|
*/ |
178 |
|
public Thread(ThreadGroup group, String name) |
179 |
|
{ |
180 |
|
this(group, null, name, 0); |
181 |
|
} |
182 |
|
|
183 |
|
/** |
184 |
|
* Allocate a new Thread object, as if by |
185 |
|
* <code>Thread(group, null, name)</code>. |
186 |
|
* |
187 |
|
* @param toRun the Runnable object to execute |
188 |
|
* @param name the name for the Thread |
189 |
|
* @throws NullPointerException if name is null |
190 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
191 |
|
*/ |
192 |
|
public Thread(Runnable toRun, String name) |
193 |
|
{ |
194 |
|
this(null, toRun, name, 0); |
195 |
|
} |
196 |
|
|
197 |
|
/** |
198 |
|
* Allocate a new Thread object, with the specified ThreadGroup and name, and |
199 |
|
* using the specified Runnable object's <code>run()</code> method to |
200 |
|
* execute. If the Runnable object is null, <code>this</code> (which is |
201 |
|
* a Runnable) is used instead. |
202 |
|
* |
203 |
|
* <p>If the ThreadGroup is null, the security manager is checked. If a |
204 |
|
* manager exists and returns a non-null object for |
205 |
|
* <code>getThreadGroup</code>, that group is used; otherwise the group |
206 |
|
* of the creating thread is used. Note that the security manager calls |
207 |
|
* <code>checkAccess</code> if the ThreadGroup is not null. |
208 |
|
* |
209 |
|
* <p>The new Thread will inherit its creator's priority and daemon status. |
210 |
|
* These can be changed with <code>setPriority</code> and |
211 |
|
* <code>setDaemon</code>. |
212 |
|
* |
213 |
|
* @param group the group to put the Thread into |
214 |
|
* @param target the Runnable object to execute |
215 |
|
* @param name the name for the Thread |
216 |
|
* @throws NullPointerException if name is null |
217 |
|
* @throws SecurityException if this thread cannot access <code>group</code> |
218 |
|
* @throws IllegalThreadStateException if group is destroyed |
219 |
|
* @see Runnable#run() |
220 |
|
* @see #run() |
221 |
|
* @see #setDaemon(boolean) |
222 |
|
* @see #setPriority(int) |
223 |
|
* @see SecurityManager#checkAccess(ThreadGroup) |
224 |
|
* @see ThreadGroup#checkAccess() |
225 |
|
*/ |
226 |
|
public Thread(ThreadGroup group, Runnable toRun, String name) |
227 |
|
{ |
228 |
|
this(group, toRun, name, 0); |
229 |
|
} |
230 |
|
|
231 |
|
/** |
232 |
|
* Allocate a new Thread object, as if by |
233 |
|
* <code>Thread(group, null, name)</code>, and give it the specified stack |
234 |
|
* size, in bytes. The stack size is <b>highly platform independent</b>, |
235 |
|
* and the virtual machine is free to round up or down, or ignore it |
236 |
|
* completely. A higher value might let you go longer before a |
237 |
|
* <code>StackOverflowError</code>, while a lower value might let you go |
238 |
|
* longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely |
239 |
|
* nothing! So be careful, and expect to need to tune this value if your |
240 |
|
* virtual machine even supports it. |
241 |
|
* |
242 |
|
* @param group the group to put the Thread into |
243 |
|
* @param target the Runnable object to execute |
244 |
|
* @param name the name for the Thread |
245 |
|
* @param size the stack size, in bytes; 0 to be ignored |
246 |
|
* @throws NullPointerException if name is null |
247 |
|
* @throws SecurityException if this thread cannot access <code>group</code> |
248 |
|
* @throws IllegalThreadStateException if group is destroyed |
249 |
|
* @since 1.4 |
250 |
|
*/ |
251 |
|
public Thread(ThreadGroup group, Runnable toRun, String name, long size) |
252 |
|
{ |
253 |
|
// Bypass System.getSecurityManager, for bootstrap efficiency. |
254 |
|
SecurityManager sm = Runtime.getSecurityManager(); |
255 |
|
if (group == null) |
256 |
|
{ |
257 |
|
if (sm != null) |
258 |
|
group = sm.getThreadGroup(); |
259 |
|
if (group == null) |
260 |
|
group = currentThread().group; |
261 |
|
} |
262 |
|
else if (sm != null) |
263 |
|
sm.checkAccess(group); |
264 |
|
this.group = group; |
265 |
|
|
266 |
|
// Use toString hack to detect null. |
267 |
|
this.name = name.toString(); |
268 |
|
this.toRun = toRun; |
269 |
|
Thread current = currentThread(); |
270 |
|
priority = current.priority; |
271 |
|
daemon = current.daemon; |
272 |
|
nativeInit(size); |
273 |
|
|
274 |
|
group.addThread(this); |
275 |
|
InheritableThreadLocal.newChildThread(this); |
276 |
|
} |
277 |
|
|
278 |
|
/** |
279 |
|
* Get the currently executing Thread. |
280 |
|
* |
281 |
|
* @return the currently executing Thread |
282 |
|
*/ |
283 |
|
public static native Thread currentThread(); |
284 |
|
|
285 |
|
/** |
286 |
|
* Yield to another thread. The Thread will not lose any locks it holds |
287 |
|
* during this time. There are no guarantees which thread will be |
288 |
|
* next to run, and it could even be this one, but most VMs will choose |
289 |
|
* the highest priority threat that has been waiting longest. |
290 |
|
*/ |
291 |
|
public static native void yield(); |
292 |
|
|
293 |
|
/** |
294 |
|
* Suspend the current Thread's execution for the specified amount of |
295 |
|
* time. The Thread will not lose any locks it has during this time. There |
296 |
|
* are no guarantees which thread will be next to run, but most VMs will |
297 |
|
* choose the highest priority threat that has been waiting longest. |
298 |
|
* |
299 |
|
* @param ms the number of milliseconds to sleep, or 0 for forever |
300 |
|
* @throws InterruptedException if the Thread is interrupted; it's |
301 |
|
* <i>interrupted status</i> will be cleared |
302 |
|
* @see #notify() |
303 |
|
* @see #wait(long) |
304 |
|
*/ |
305 |
|
public static void sleep(long ms) throws InterruptedException |
306 |
|
{ |
307 |
|
sleep(ms, 0); |
308 |
|
} |
309 |
|
|
310 |
|
/** |
311 |
|
* Suspend the current Thread's execution for the specified amount of |
312 |
|
* time. The Thread will not lose any locks it has during this time. There |
313 |
|
* are no guarantees which thread will be next to run, but most VMs will |
314 |
|
* choose the highest priority threat that has been waiting longest. |
315 |
|
* |
316 |
|
* <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do |
317 |
|
* not offer that fine a grain of timing resolution. Besides, there is |
318 |
|
* no guarantee that this thread can start up immediately when time expires, |
319 |
|
* because some other thread may be active. So don't expect real-time |
320 |
|
* performance. |
321 |
|
* |
322 |
|
* @param ms the number of milliseconds to sleep, or 0 for forever |
323 |
|
* @param ns the number of extra nanoseconds to sleep (0-999999) |
324 |
|
* @throws InterruptedException if the Thread is interrupted; it's |
325 |
|
* <i>interrupted status</i> will be cleared |
326 |
|
* @throws IllegalArgumentException if ns is invalid |
327 |
|
* @see #notify() |
328 |
|
* @see #wait(long, int) |
329 |
|
*/ |
330 |
|
public static native void sleep(long ms, int ns) throws InterruptedException; |
331 |
|
|
332 |
static int numAnonymousThreadsCreated = 0; |
/** |
333 |
|
* Start this Thread, calling the run() method of the Runnable this Thread |
334 |
|
* was created with, or else the run() method of the Thread itself. This |
335 |
|
* is the only way to start a new thread; calling run by yourself will just |
336 |
|
* stay in the same thread. The virtual machine will remove the thread from |
337 |
|
* its thread group when the run() method completes. |
338 |
|
* |
339 |
|
* @throws IllegalThreadStateException if the thread has already started |
340 |
|
* @see #run() |
341 |
|
*/ |
342 |
|
public synchronized native void start(); |
343 |
|
|
344 |
|
/** |
345 |
|
* The method of Thread that will be run if there is no Runnable object |
346 |
|
* associated with the Thread. Thread's implementation does nothing at all. |
347 |
|
* |
348 |
|
* @see #start() |
349 |
|
* @see #Thread(ThreadGroup, Runnable, String) |
350 |
|
*/ |
351 |
|
public void run() |
352 |
|
{ |
353 |
|
if (toRun != null) |
354 |
|
toRun.run(); |
355 |
|
} |
356 |
|
|
357 |
/** Allocate a new Thread object, with the same ThreadGroup |
/** |
358 |
** as the calling thread, with an automatic name, and using |
* Cause this Thread to stop abnormally because of the throw of a ThreadDeath |
359 |
** Thread's <CODE>run()</CODE> method to execute.<P> |
* error. If you stop a Thread that has not yet started, it will stop |
360 |
** |
* immediately when it is actually started. |
361 |
** The new Thread will inherit its creator's priority and |
* |
362 |
** will be marked as a daemon if its creator is a daemon.<P> |
* <p>This is inherently unsafe, as it can interrupt synchronized blocks and |
363 |
** |
* leave data in bad states. Hence, there is a security check: |
364 |
** This method is identical to calling |
* <code>checkAccess(this)</code>, plus another one if the current thread |
365 |
** <CODE>Thread(null,null,<I>fake name</I>)</CODE>, where the |
* is not this: <code>RuntimePermission("stopThread")</code>. If you must |
366 |
** fake name in this case is automatically generated with the |
* catch a ThreadDeath, be sure to rethrow it after you have cleaned up. |
367 |
** name "Thread-" + <I>arbitrary integer</I>. |
* ThreadDeath is the only exception which does not print a stack trace when |
368 |
**/ |
* the thread dies. |
369 |
public Thread() { |
* |
370 |
this(null,null,null); |
* @throws SecurityException if you cannot stop the Thread |
371 |
} |
* @see #interrupt() |
372 |
|
* @see #checkAccess() |
373 |
/** Allocate a new Thread object, with the same ThreadGroup |
* @see #start() |
374 |
** as the calling thread, with an automatic name, and using |
* @see ThreadDeath |
375 |
** the specified Runnable object's <CODE>run()</CODE> method |
* @see ThreadGroup#uncaughtException(Thread, Throwable) |
376 |
** to execute. If the Runnable object is null, Thread's |
* @see SecurityManager#checkAccess(Thread) |
377 |
** <CODE>run()</CODE> will be called instead.<P> |
* @see SecurityManager#checkPermission(Permission) |
378 |
** |
* @deprecated unsafe operation, try not to use |
379 |
** The new Thread will inherit its creator's priority and |
*/ |
380 |
** will be marked as a daemon if its creator is a daemon.<P> |
public final void stop() |
381 |
** |
{ |
382 |
** This method is identical to calling |
stop(new ThreadDeath()); |
383 |
** <CODE>Thread(null,target,<I>fake name</I>)</CODE>, where the |
} |
384 |
** fake name in this case is automatically generated with the |
|
385 |
** name "Thread-" + <I>arbitrary integer</I>. |
/** |
386 |
** |
* Cause this Thread to stop abnormally and throw the specified exception. |
387 |
** @param toRun the Runnable object to execute. |
* If you stop a Thread that has not yet started, it will stop immediately |
388 |
**/ |
* when it is actually started. <b>WARNING</b>This bypasses Java security, |
389 |
public Thread(Runnable toRun) { |
* and can throw a checked exception which the call stack is unprepared to |
390 |
this(null,toRun); |
* handle. Do not abuse this power. |
391 |
} |
* |
392 |
|
* <p>This is inherently unsafe, as it can interrupt synchronized blocks and |
393 |
/** Allocate a new Thread object, with the specified ThreadGroup, |
* leave data in bad states. Hence, there is a security check: |
394 |
** with an automatic name, and using the specified Runnable |
* <code>checkAccess(this)</code>, plus another one if the current thread |
395 |
** object's <CODE>run()</CODE> method to execute. If the |
* is not this: <code>RuntimePermission("stopThread")</code>. If you must |
396 |
** Runnable object is null, Thread's <CPDE>run()</CODE> will be |
* catch a ThreadDeath, be sure to rethrow it after you have cleaned up. |
397 |
** called instead. If the ThreadGroup object is null, the Thread |
* ThreadDeath is the only exception which does not print a stack trace when |
398 |
** will get the same ThreadGroup as the creating Thread.<P> |
* the thread dies. |
399 |
** |
* |
400 |
** The new Thread will inherit its creator's priority and |
* @param t the Throwable to throw when the Thread dies |
401 |
** will be marked as a daemon if its creator is a daemon.<P> |
* @throws SecurityException if you cannot stop the Thread |
402 |
** |
* @throws NullPointerException in the calling thread, if t is null |
403 |
** This method is identical to calling |
* @see #interrupt() |
404 |
** <CODE>Thread(null,target,<I>fake name</I>)</CODE>, where the |
* @see #checkAccess() |
405 |
** fake name in this case is automatically generated with the |
* @see #start() |
406 |
** name "Thread-" + <I>arbitrary integer</I>. |
* @see ThreadDeath |
407 |
** |
* @see ThreadGroup#uncaughtException(Thread, Throwable) |
408 |
** @param group the group to put the Thread into. |
* @see SecurityManager#checkAccess(Thread) |
409 |
** @param target the Runnable object to execute. |
* @see SecurityManager#checkPermission(Permission) |
410 |
** |
* @deprecated unsafe operation, try not to use |
411 |
** @exception SecurityException if this thread cannot access the |
*/ |
412 |
** specified ThreadGroup. |
public final synchronized void stop(Throwable t) |
413 |
**/ |
{ |
414 |
public Thread(ThreadGroup group, Runnable toRun) { |
if (t == null) |
415 |
this(group,toRun,null); |
throw new NullPointerException(); |
416 |
} |
// Bypass System.getSecurityManager, for bootstrap efficiency. |
417 |
|
SecurityManager sm = Runtime.getSecurityManager(); |
418 |
/** Allocate a new Thread object, with the same ThreadGroup |
if (sm != null) |
419 |
** as the calling thread, with the specified name, and using |
{ |
420 |
** Thread's <CODE>run()</CODE> method to execute.<P> |
sm.checkAccess(this); |
421 |
** |
if (this != currentThread()) |
422 |
** The new Thread will inherit its creator's priority and |
sm.checkPermission(new RuntimePermission("stopThread")); |
423 |
** will be marked as a daemon if its creator is a daemon.<P> |
} |
424 |
** |
group.removeThread(this); |
425 |
** This method is identical to calling |
nativeStop(t); |
426 |
** <CODE>Thread(null,null,name)</CODE>. |
} |
427 |
** |
|
428 |
** @param name the name for the Thread. |
/** |
429 |
**/ |
* Interrupt this Thread. First, there is a security check, |
430 |
public Thread(String name) { |
* <code>checkAccess</code>. Then, depending on the current state of the |
431 |
this(null,null,name); |
* thread, various actions take place: |
432 |
} |
* |
433 |
|
* <p>If the thread is waiting because of {@link #wait()}, |
434 |
/** Allocate a new Thread object, with the same ThreadGroup |
* {@link #sleep(long)}, or {@link #join()}, its <i>interrupt status</i> |
435 |
** as the calling thread, with the specified name, and using |
* will be cleared, and an InterruptedException will be thrown. Notice that |
436 |
** the specified Runnable object's <CODE>run()</CODE> method |
* this case is only possible if an external thread called interrupt(). |
437 |
** to execute. If the Runnable object is null, Thread's |
* |
438 |
** <CPDE>run()</CODE> will be called instead.<P> |
* <p>If the thread is blocked in an interruptible I/O operation, in |
439 |
** |
* {@link java.nio.channels.InterruptibleChannel}, the <i>interrupt |
440 |
** The new Thread will inherit its creator's priority and |
* status</i> will be set, and ClosedByInterruptException will be thrown. |
441 |
** will be marked as a daemon if its creator is a daemon.<P> |
* |
442 |
** |
* <p>If the thread is blocked on a {@link java.nio.channels.Selector}, the |
443 |
** This method is identical to calling |
* <i>interrupt status</i> will be set, and the selection will return, with |
444 |
** <CODE>Thread(null,target,name)</CODE>. |
* a possible non-zero value, as though by the wakeup() method. |
445 |
** |
* |
446 |
** @param toRun the Runnable object to execute. |
* <p>Otherwise, the interrupt status will be set. |
447 |
** @param name the name for the Thread. |
* |
448 |
**/ |
* @throws SecurityException if you cannot modify this Thread |
449 |
public Thread(Runnable toRun, String name) { |
*/ |
450 |
this(null,toRun,name); |
public synchronized void interrupt() |
451 |
} |
{ |
452 |
|
checkAccess(); |
453 |
public Thread(ThreadGroup group, String name) { |
nativeInterrupt(); |
454 |
this(group,null,name); |
} |
455 |
} |
|
456 |
|
/** |
457 |
/** Allocate a new Thread object, with the specified ThreadGroup, |
* Determine whether the current Thread has been interrupted, and clear |
458 |
** with the specified name, and using the specified Runnable |
* the <i>interrupted status</i> in the process. |
459 |
** object's <CODE>run()</CODE> method to execute. If the |
* |
460 |
** Runnable object is null, Thread's <CPDE>run()</CODE> will be |
* @return whether the current Thread has been interrupted |
461 |
** called instead. If the ThreadGroup object is null, the Thread |
* @see #isInterrupted() |
462 |
** will get the same ThreadGroup as the creating Thread.<P> |
*/ |
463 |
** |
public static native boolean interrupted(); |
464 |
** The new Thread will inherit its creator's priority and |
|
465 |
** will be marked as a daemon if its creator is a daemon. |
/** |
466 |
** |
* Determine whether the given Thread has been interrupted, but leave |
467 |
** @param group the group to put the Thread into. |
* the <i>interrupted status</i> alone in the process. |
468 |
** @param target the Runnable object to execute. |
* |
469 |
** @param name the name for the Thread. |
* @return whether the current Thread has been interrupted |
470 |
** |
* @see #interrupted() |
471 |
** @exception SecurityException if this thread cannot access the |
*/ |
472 |
** specified ThreadGroup. |
public native boolean isInterrupted(); |
473 |
**/ |
|
474 |
public Thread(ThreadGroup group, Runnable toRun, String name) { |
/** |
475 |
if(group != null) { |
* Originally intended to destroy this thread, this method was never |
476 |
this.group = group; |
* implemented by Sun, and is hence a no-op. |
477 |
group.checkAccess(); |
*/ |
478 |
} else { |
public void destroy() |
479 |
this.group = currentThread().getThreadGroup(); |
{ |
480 |
} |
} |
481 |
|
|
482 |
if ( name != null ) |
/** |
483 |
{ |
* Determine whether this Thread is alive. A thread which is alive has |
484 |
this.name = name; |
* started and not yet died. |
485 |
} else { |
* |
486 |
this.name = "Thread-" + (++numAnonymousThreadsCreated); |
* @return whether this Thread is alive |
487 |
} |
*/ |
488 |
|
public final native boolean isAlive(); |
489 |
this.toRun = toRun; |
|
490 |
|
/** |
491 |
priority = currentThread().getPriority(); |
* Suspend this Thread. It will not come back, ever, unless it is resumed. |
492 |
daemon = currentThread().isDaemon(); |
* |
493 |
contextClassLoader = currentThread().getContextClassLoader(); |
* <p>This is inherently unsafe, as the suspended thread still holds locks, |
494 |
nativeInit(); |
* and can potentially deadlock your program. Hence, there is a security |
495 |
|
* check: <code>checkAccess</code>. |
496 |
this.group.addThread(this); |
* |
497 |
InheritableThreadLocal.newChildThread(this); |
* @throws SecurityException if you cannot suspend the Thread |
498 |
} |
* @see #checkAccess() |
499 |
|
* @see #resume() |
500 |
/** Get the currently executing Thread. |
* @deprecated unsafe operation, try not to use |
501 |
** @return the currently executing Thread. |
*/ |
502 |
**/ |
public final synchronized void suspend() |
503 |
public static native Thread currentThread(); |
{ |
504 |
|
checkAccess(); |
505 |
/** Suspend the current Thread's execution for the specified |
nativeSuspend(); |
506 |
** amount of time. The Thread will not lose any locks it has |
} |
507 |
** during this time. |
|
508 |
** |
/** |
509 |
** @param ms the number of milliseconds to sleep. |
* Resume this Thread. If the thread is not suspended, this method does |
510 |
** @exception InterruptedException if the Thread is interrupted |
* nothing. To mirror suspend(), there may be a security check: |
511 |
** by another Thread. |
* <code>checkAccess</code>. |
512 |
** @exception SecurityException if you cannot modify this Thread. |
* |
513 |
**/ |
* @throws SecurityException if you cannot resume the Thread |
514 |
public static void sleep(long ms) throws InterruptedException { |
* @see #checkAccess() |
515 |
sleep(ms,0); |
* @see #suspend() |
516 |
} |
* @deprecated pointless, since suspend is deprecated |
517 |
|
*/ |
518 |
/** Suspend the current Thread's execution for the specified |
public final synchronized void resume() |
519 |
** amount of time. The Thread will not lose any locks it has |
{ |
520 |
** during this time. |
checkAccess(); |
521 |
** |
nativeResume(); |
522 |
** @param ms the number of milliseconds to sleep. |
} |
523 |
** @param ns the number of extra nanoseconds to sleep (0-999999). |
|
524 |
** @exception InterruptedException if the Thread is interrupted |
/** |
525 |
** by another Thread. |
* Set this Thread's priority. There may be a security check, |
526 |
**/ |
* <code>checkAccess</code>, then the priority is set to the smaller of |
527 |
public static native void sleep(long ms, int ns) throws InterruptedException; |
* priority and the ThreadGroup maximum priority. |
528 |
|
* |
529 |
/** Start this Thread, calling the run() method of the Runnable |
* @param priority the new priority for this Thread |
530 |
** this Thread was created with or else the run() method of the |
* @throws IllegalArgumentException if priority exceeds MIN_PRIORITY or |
531 |
** Thread itself. |
* MAX_PRIORITY |
532 |
**/ |
* @throws SecurityException if you cannot modify this Thread |
533 |
public synchronized native void start(); |
* @see #getPriority() |
534 |
|
* @see #checkAccess() |
535 |
/** The method of Thread that will be run if there is no Runnable |
* @see ThreadGroup#getMaxPriority() |
536 |
** object associated with the Thread.<P> |
* @see #MIN_PRIORITY |
537 |
** |
* @see #MAX_PRIORITY |
538 |
** Thread's implementation does nothing at all. |
*/ |
539 |
**/ |
public final void setPriority(int priority) |
540 |
public void run() { |
{ |
541 |
if (toRun != null) |
checkAccess(); |
542 |
toRun.run(); |
if (priority < MIN_PRIORITY || priority > MAX_PRIORITY) |
543 |
} |
throw new IllegalArgumentException("Invalid thread priority value " |
544 |
|
+ priority + "."); |
545 |
/** Cause this Thread to stop abnormally and throw a ThreadDeath |
this.priority = Math.min(priority, group.getMaxPriority()); |
546 |
** exception.<P> |
nativeSetPriority(this.priority); |
547 |
** |
} |
548 |
** If you stop a Thread that has not yet started, it will stop |
|
549 |
** immediately when it is actually started.<P> |
/** |
550 |
** |
* Get this Thread's priority. |
551 |
** @deprecated unsafe operation. |
* |
552 |
** |
* @return the Thread's priority |
553 |
** @exception SecurityException if you cannot modify this Thread. |
*/ |
554 |
** @XXX it doesn't yet implement that second requirement. |
public final int getPriority() |
555 |
**/ |
{ |
556 |
public final void stop() { |
return priority; |
557 |
stop(new ThreadDeath()); |
} |
558 |
} |
|
559 |
|
/** |
560 |
/** Cause this Thread to stop abnormally and throw the specified |
* Set this Thread's name. There may be a security check, |
561 |
** exception.<P> |
* <code>checkAccess</code>. |
562 |
** |
* |
563 |
** If you stop a Thread that has not yet started, it will stop |
* @param name the new name for this Thread |
564 |
** immediately when it is actually started.<P> |
* @throws NullPointerException if name is null |
565 |
** |
* @throws SecurityException if you cannot modify this Thread |
566 |
** @deprecated unsafe operation. |
*/ |
567 |
** |
public final void setName(String name) |
568 |
** @param t the Throwable to throw when the Thread dies. |
{ |
569 |
** @exception SecurityException if you cannot modify this Thread. |
checkAccess(); |
570 |
** @XXX it doesn't yet implement that second requirement. |
// Use toString hack to detect null. |
571 |
**/ |
this.name = name.toString(); |
572 |
public final synchronized void stop(Throwable t) { |
} |
573 |
checkAccess(); |
|
574 |
group.removeThread(this); |
/** |
575 |
nativeStop(t); |
* Get this Thread's name. |
576 |
} |
* |
577 |
|
* @return this Thread's name |
578 |
/** |
*/ |
579 |
** Yield to another thread |
public final String getName() |
580 |
**/ |
{ |
581 |
public static synchronized native void yield(); |
return name; |
582 |
|
} |
583 |
/** Interrupt this Thread. |
|
584 |
** It is not clear whether locks this Thread has should be released. |
/** |
585 |
** This operation will only take place if the Thread is suspended |
* Get the ThreadGroup this Thread belongs to. If the thread has died, this |
586 |
** or is sleeping. |
* returns null. |
587 |
** @exception SecurityException if you cannot modify this Thread. |
* |
588 |
**/ |
* @return this Thread's ThreadGroup |
589 |
public synchronized void interrupt() { |
*/ |
590 |
checkAccess(); |
public final ThreadGroup getThreadGroup() |
591 |
nativeInterrupt(); |
{ |
592 |
} |
return group; |
593 |
|
} |
594 |
/** Destroy this thread. Don't even bother to clean up locks. |
|
595 |
** @exception SecurityException if you cannot modify this Thread. |
/** |
596 |
**/ |
* Get the number of active threads in the current Thread's ThreadGroup. |
597 |
public synchronized void destroy() { |
* This implementation calls |
598 |
checkAccess(); |
* <code>currentThread().getThreadGroup().activeCount()</code>. |
599 |
group.removeThread(this); |
* |
600 |
nativeDestroy(); |
* @return the number of active threads in the current ThreadGroup |
601 |
} |
* @see ThreadGroup#activeCount() |
602 |
|
*/ |
603 |
/** Suspend this Thread. It will not come back, ever, unless |
public static int activeCount() |
604 |
** it is resumed. It is not clear whether locks should be |
{ |
605 |
** released until resumption, but it is likely. |
return currentThread().group.activeCount(); |
606 |
** |
} |
607 |
** @deprecated depends on <code>suspend()</code>. |
|
608 |
** |
/** |
609 |
** @exception SecurityException if you cannot modify this Thread. |
* Copy every active thread in the current Thread's ThreadGroup into the |
610 |
**/ |
* array. Extra threads are silently ignored. This implementation calls |
611 |
public final synchronized void suspend() { |
* <code>getThreadGroup().enumerate(array)</code>, which may have a |
612 |
checkAccess(); |
* security check, <code>checkAccess(group)</code>. |
613 |
nativeSuspend(); |
* |
614 |
} |
* @param array the array to place the Threads into |
615 |
|
* @return the number of Threads placed into the array |
616 |
/** Resume this Thread. If the thread is not suspended, this |
* @throws NullPointerException if array is null |
617 |
** method does nothing. |
* @throws SecurityException if you cannot access the ThreadGroup |
618 |
** |
* @see ThreadGroup#enumerate(Thread[]) |
619 |
** @deprecated depends on <code>suspend()</code>. |
* @see #activeCount() |
620 |
** |
* @see SecurityManager#checkAccess(ThreadGroup) |
621 |
** @exception SecurityException if you cannot modify this Thread. |
*/ |
622 |
**/ |
public static int enumerate(Thread[] array) |
623 |
public final synchronized void resume() { |
{ |
624 |
checkAccess(); |
return currentThread().group.enumerate(array); |
625 |
nativeResume(); |
} |
626 |
} |
|
627 |
|
/** |
628 |
/** Wait forever for the Thread in question to die. |
* Count the number of stack frames in this Thread. The Thread in question |
629 |
** @exception InterruptedException if this Thread is interrupted |
* must be suspended when this occurs. |
630 |
** while waiting. |
* |
631 |
**/ |
* @return the number of stack frames in this Thread |
632 |
public final void join() throws InterruptedException { |
* @throws IllegalThreadStateException if this Thread is not suspended |
633 |
join(0,0); |
* @deprecated pointless, since suspend is deprecated |
634 |
} |
*/ |
635 |
|
public native int countStackFrames(); |
636 |
/** Wait the specified amount of time for the Thread in question to |
|
637 |
** die. |
/** |
638 |
** @param ms the number of milliseconds to wait, or 0 for forever. |
* Wait the specified amount of time for the Thread in question to die. |
639 |
** @exception InterruptedException if this Thread is interrupted |
* |
640 |
** while waiting. |
* @param ms the number of milliseconds to wait, or 0 for forever |
641 |
**/ |
* @throws InterruptedException if the Thread is interrupted; it's |
642 |
public final void join(long ms) throws InterruptedException { |
* <i>interrupted status</i> will be cleared |
643 |
join(ms,0); |
*/ |
644 |
} |
public final void join(long ms) throws InterruptedException |
645 |
|
{ |
646 |
/** Wait the specified amount of time for the Thread in question to |
join(ms, 0); |
647 |
** die. |
} |
648 |
** @param ms the number of milliseconds to wait, or 0 for forever. |
|
649 |
** @param ns the number of nanoseconds (0-999999) to wait, or 0 for |
/** |
650 |
** forever. |
* Wait the specified amount of time for the Thread in question to die. |
651 |
** @exception InterruptedException if this Thread is interrupted |
* |
652 |
** while waiting. |
* <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do |
653 |
** @XXX a ThreadListener would be nice. Then perhaps this could be |
* not offer that fine a grain of timing resolution. Besides, there is |
654 |
** made efficient. |
* no guarantee that this thread can start up immediately when time expires, |
655 |
**/ |
* because some other thread may be active. So don't expect real-time |
656 |
public final void join(long ms, int ns) throws InterruptedException { |
* performance. |
657 |
if(ms == 0 && ns == 0) { |
* |
658 |
while(isAlive()) |
* @param ms the number of milliseconds to wait, or 0 for forever |
659 |
currentThread().sleep(1); |
* @param ns the number of extra nanoseconds to sleep (0-999999) |
660 |
} else { |
* @throws InterruptedException if the Thread is interrupted; it's |
661 |
for(long i=0;i<ms;i++) { |
* <i>interrupted status</i> will be cleared |
662 |
if(!isAlive()) |
* @throws IllegalArgumentException if ns is invalid |
663 |
return; |
* @XXX A ThreadListener would be nice, to make this efficient. |
664 |
currentThread().sleep(1); |
*/ |
665 |
} |
public final void join(long ms, int ns) throws InterruptedException |
666 |
currentThread().sleep(0,ns); |
{ |
667 |
} |
Thread current = currentThread(); |
668 |
} |
if (ms == 0 && ns == 0) |
669 |
|
while (isAlive()) |
670 |
/** Print a stack trace of the current thread to stderr using |
current.sleep(1); |
671 |
** the same format as Throwable's printStackTrace() method. |
else |
672 |
**/ |
{ |
673 |
public static void dumpStack() { |
while (--ms >= 0) |
674 |
new Throwable().printStackTrace(); |
{ |
675 |
} |
if (! isAlive()) |
676 |
|
return; |
677 |
|
current.sleep(1); |
678 |
/** Set this Thread's priority. |
} |
679 |
** @param priority the new priority for this Thread. |
current.sleep(0, ns); |
680 |
** @exception SecurityException if you cannot modify this Thread. |
} |
681 |
**/ |
} |
682 |
public final void setPriority(int priority) { |
|
683 |
checkAccess(); |
/** |
684 |
if(priority < MIN_PRIORITY |
* Wait forever for the Thread in question to die. |
685 |
|| priority > MAX_PRIORITY |
* |
686 |
|| priority > group.getMaxPriority()) |
* @throws InterruptedException if the Thread is interrupted; it's |
687 |
throw new IllegalArgumentException("Invalid thread priority value " + priority + "."); |
* <i>interrupted status</i> will be cleared |
688 |
this.priority = priority; |
*/ |
689 |
nativeSetPriority(priority); |
public final void join() throws InterruptedException |
690 |
} |
{ |
691 |
|
join(0, 0); |
692 |
/** Get this Thread's priority. |
} |
693 |
** @return the Thread's priority. |
|
694 |
**/ |
/** |
695 |
public final int getPriority() { |
* Print a stack trace of the current thread to stderr using the same |
696 |
return priority; |
* format as Throwable's printStackTrace() method. |
697 |
} |
* |
698 |
|
* @see Throwable#printStackTrace() |
699 |
/** Set this Thread's name. |
*/ |
700 |
** @param name the new name for this Thread. |
public static void dumpStack() |
701 |
** @exception SecurityException if you cannot modify this Thread. |
{ |
702 |
**/ |
new Throwable().printStackTrace(); |
703 |
public final void setName(String name) { |
} |
704 |
checkAccess(); |
|
705 |
this.name = name; |
/** |
706 |
} |
* Set the daemon status of this Thread. If this is a daemon Thread, then |
707 |
|
* the VM may exit even if it is still running. This may only be called |
708 |
/** Get this Thread's name. |
* before the Thread starts running. There may be a security check, |
709 |
** @return this Thread's name. |
* <code>checkAccess</code>. |
710 |
**/ |
* |
711 |
public final String getName() { |
* @param daemon whether this should be a daemon thread or not |
712 |
return name; |
* @throws SecurityException if you cannot modify this Thread |
713 |
} |
* @throws IllegalThreadStateException if the Thread is active |
714 |
|
* @see #isDaemon() |
715 |
/** Get the ThreadGroup this Thread belongs to. |
* @see #checkAccess() |
716 |
** @return this Thread's ThreadGroup. |
*/ |
717 |
**/ |
public final void setDaemon(boolean daemon) |
718 |
public final ThreadGroup getThreadGroup() { |
{ |
719 |
return group; |
if (isAlive() || group == null) |
720 |
} |
throw new IllegalThreadStateException(); |
721 |
|
checkAccess(); |
722 |
/** Set the daemon status of this Thread. If this is a |
this.daemon = daemon; |
723 |
** daemon Thread, then the VM may exit even if it is still |
} |
724 |
** running. This may only be called when the Thread is not |
|
725 |
** running. |
/** |
726 |
** |
* Tell whether this is a daemon Thread or not. |
727 |
** @specnote It is possible that this should only be called |
* |
728 |
** if the Thread has not been started. This |
* @return whether this is a daemon Thread or not |
729 |
** interpretation was easier to implement, though, |
* @see #setDaemon(boolean) |
730 |
** so it's the one I chose :) |
*/ |
731 |
** @param daemon whether this should be a daemon thread or not. |
public final boolean isDaemon() |
732 |
** @exception SecurityException if you cannot modify this Thread. |
{ |
733 |
** @exception IllegalThreadStateException if the Thread is active. |
return daemon; |
734 |
**/ |
} |
735 |
public final void setDaemon(boolean daemon) { |
|
736 |
this.daemon = daemon; |
/** |
737 |
} |
* Check whether the current Thread is allowed to modify this Thread. This |
738 |
|
* passes the check on to <code>SecurityManager.checkAccess(this)</code>. |
739 |
/** Tell whether this is a daemon Thread or not. |
* |
740 |
** @return whether this is a daemon Thread or not. |
* @throws SecurityException if the current Thread cannot modify this Thread |
741 |
**/ |
* @see SecurityManager#checkAccess(Thread) |
742 |
public final boolean isDaemon() { |
*/ |
743 |
return daemon; |
public final void checkAccess() |
744 |
} |
{ |
745 |
|
// Bypass System.getSecurityManager, for bootstrap efficiency. |
746 |
|
SecurityManager sm = Runtime.getSecurityManager(); |
747 |
/** Get the number of active threads in the current Thread's |
if (sm != null) |
748 |
** ThreadGroup. This implementation calls |
sm.checkAccess(this); |
749 |
** <CODE>currentThread().getThreadGroup().activeCount()</CODE>. |
} |
750 |
** @return the number of active threads in the current Thread's |
|
751 |
** ThreadGroup. |
/** |
752 |
**/ |
* Return a human-readable String representing this Thread. The format of |
753 |
public static int activeCount() { |
* the string is:<br> |
754 |
return currentThread().group.activeCount(); |
* <code>"Thread[" + getName() + ',' + getPriority() + ',' |
755 |
} |
* + (getThreadGroup() == null ? "" : getThreadGroup().getName()) |
756 |
|
+ ']'</code>. |
757 |
/** Copy every active thread in the current Thread's ThreadGroup |
* |
758 |
** into the array. This implementation calls |
* @return a human-readable String representing this Thread |
759 |
** <CODE>getThreadGroup().enumerate(array)</CODE> |
*/ |
760 |
** @param array the array to place the Threads into. |
public String toString() |
761 |
** @return the number of Threads placed into the array. |
{ |
762 |
**/ |
return "Thread[" + name + ',' + priority + ',' |
763 |
public static int enumerate(Thread[] array) { |
+ (group == null ? "" : group.name) + ']'; |
764 |
return currentThread().group.enumerate(array); |
} |
765 |
} |
|
766 |
|
/** |
767 |
/** Count the number of stack frames in this Thread. The Thread |
* Returns the context classloader of this Thread. The context |
768 |
** in question must be suspended when this occurs. |
* classloader can be used by code that want to load classes depending |
769 |
** |
* on the current thread. Normally classes are loaded depending on |
770 |
** @deprecated depends on <code>suspend</code>. |
* the classloader of the current class. There may be a security check |
771 |
** @return the number of stack frames in this Thread. |
* for <code>RuntimePermission("getClassLoader")</code> if the caller's |
772 |
** @exception IllegalThreadStateException if this Thread is |
* class loader is not null or an ancestor of this thread's context class |
773 |
** not suspended. |
* loader. |
774 |
**/ |
* |
775 |
public native int countStackFrames(); |
* @return the context class loader |
776 |
|
* @throws SecurityException when permission is denied |
777 |
|
* @see setContextClassLoader(ClassLoader) |
778 |
/** Determine whether the current Thread has been interrupted. |
* @since 1.2 |
779 |
** @return whether the current Thread has been interrupted. |
*/ |
780 |
**/ |
public ClassLoader getContextClassLoader() |
781 |
public static boolean interrupted() { |
{ |
782 |
return currentThread().isInterrupted(); |
// Bypass System.getSecurityManager, for bootstrap efficiency. |
783 |
} |
SecurityManager sm = Runtime.getSecurityManager(); |
784 |
|
if (sm != null) |
785 |
/** Determine whether this Thread has been interrupted. |
// XXX Don't check this if the caller's class loader is an ancestor. |
786 |
** @return whether this Thread has been interrupted. |
sm.checkPermission(new RuntimePermission("getClassLoader")); |
787 |
**/ |
return contextClassLoader; |
788 |
public native boolean isInterrupted(); |
} |
789 |
|
|
790 |
/** Determine whether this Thread is alive. |
/** |
791 |
** @return whether this Thread is alive. |
* Sets the context classloader for this Thread. When not explicitly set, |
792 |
**/ |
* the context classloader for a thread is the same as the context |
793 |
public final native boolean isAlive(); |
* classloader of the thread that created this thread. The first thread has |
794 |
|
* as context classloader the system classloader. There may be a security |
795 |
|
* check for <code>RuntimePermission("setContextClassLoader")</code>. |
796 |
/** Check whether the current Thread is allowed to |
* |
797 |
** modify this Thread. |
* @param classloader the new context class loader |
798 |
** @exception SecurityException if the current Thread cannot |
* @throws SecurityException when permission is denied |
799 |
** modify this Thread. |
* @see getContextClassLoader() |
800 |
**/ |
* @since 1.2 |
801 |
public final void checkAccess() { |
*/ |
802 |
SecurityManager sm = System.getSecurityManager(); |
public void setContextClassLoader(ClassLoader classloader) |
803 |
if(sm != null) { |
{ |
804 |
sm.checkAccess(this); |
SecurityManager sm = System.getSecurityManager(); |
805 |
} |
if (sm != null) |
806 |
} |
sm.checkPermission(new RuntimePermission("setContextClassLoader")); |
807 |
|
this.contextClassLoader = classloader; |
808 |
/** Return a human-readable String representing this Thread. |
} |
809 |
** The format of the string is |
|
810 |
** "<CODE>Thread[<name>,<priority>,<thread group name>]</CODE>" |
/** |
811 |
** @return a human-readable String representing this Thread. |
* Checks whether the current thread holds the monitor on a given object. |
812 |
**/ |
* This allows you to do <code>assert Thread.holdsLock(obj)</code>. |
813 |
public String toString() { |
* |
814 |
return "Thread[" + getName() + "," + getPriority() + "," + getThreadGroup().getName() + "]"; |
* @param obj the object to check |
815 |
} |
* @return true if the current thread is currently synchronized on obj |
816 |
|
* @throws NullPointerException if obj is null |
817 |
final native void nativeInit(); |
* @since 1.4 |
818 |
final native void nativeStop(Throwable t); |
*/ |
819 |
final native void nativeInterrupt(); |
public static native boolean holdsLock(Object obj); |
820 |
final native void nativeDestroy(); |
|
821 |
final native void nativeSuspend(); |
/** |
822 |
final native void nativeResume(); |
* Whatever native initialization must be done in the constructor. |
823 |
final native void nativeSetPriority(int newPriority); |
* |
824 |
|
* @param size the requested stack size; may be ignored, and 0 signifies the |
825 |
/** |
* default amount |
826 |
* Returns the context classloader of this Thread. The context |
* @see #Thread(ThreadGroup, Runnable, String, long) |
827 |
* classloader can be used by code that want to load classes depending |
*/ |
828 |
* on the current thread. Normally classes are loaded depending on |
final native void nativeInit(long size); |
829 |
* the classloader of the current class. |
|
830 |
* |
/** |
831 |
* @exception SecurityException when the calling code does not have |
* Stop a thread by throwing the given exception. |
832 |
* <code>RuntimePermission("getClassLoader")</code>. |
* |
833 |
*/ |
* @param t the exception to throw, non-null |
834 |
public ClassLoader getContextClassLoader() |
* @see #stop(Throwable) |
835 |
{ |
*/ |
836 |
SecurityManager sm = System.getSecurityManager(); |
final native void nativeStop(Throwable t); |
837 |
if (sm != null) |
|
838 |
sm.checkPermission(new RuntimePermission("getClassLoader")); |
/** |
839 |
|
* Interrupt a thread. |
840 |
return contextClassLoader; |
* |
841 |
} |
* @see #interrupt() |
842 |
|
*/ |
843 |
/** |
final native void nativeInterrupt(); |
844 |
* Sets the context classloader for this Thread. When not explicitly |
|
845 |
* set the context classloader for a thread is the same as the context |
/** |
846 |
* classloader of the thread that created this thread. The first |
* Suspend a thread. |
847 |
* thread has as context classloader the system classloader. |
* |
848 |
* |
* @see #suspend() |
849 |
* @exception SecurityException when the calling code does not have |
*/ |
850 |
* <code>RuntimePermission("setContextClassLoader")</code>. |
final native void nativeSuspend(); |
851 |
*/ |
|
852 |
public void setContextClassLoader(ClassLoader classloader) |
/** |
853 |
{ |
* Resume a suspended thread. |
854 |
SecurityManager sm = System.getSecurityManager(); |
* |
855 |
if (sm != null) |
* @see #resume() |
856 |
sm.checkPermission(new RuntimePermission("setContextClassLoader")); |
*/ |
857 |
|
final native void nativeResume(); |
858 |
this.contextClassLoader = classloader; |
|
859 |
} |
/** |
860 |
} |
* Set the new priority of a thread. |
861 |
|
* |
862 |
|
* @param newPriority the new priority, in range |
863 |
|
* @see #setPriority(int) |
864 |
|
*/ |
865 |
|
final native void nativeSetPriority(int newPriority); |
866 |
|
} // class Thread |