GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* Thread -- an independent thread of executable code 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 3: Free Software Foundation 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: package java.lang; 40: 41: import java.util.Map; 42: import java.util.WeakHashMap; 43: 44: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 45: * "The Java Language Specification", ISBN 0-201-63451-1 46: * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. 47: * Status: Believed complete to version 1.4, with caveats. We do not 48: * implement the deprecated (and dangerous) stop, suspend, and resume 49: * methods. Security implementation is not complete. 50: */ 51: 52: /** 53: * Thread represents a single thread of execution in the VM. When an 54: * application VM starts up, it creates a non-daemon Thread which calls the 55: * main() method of a particular class. There may be other Threads running, 56: * such as the garbage collection thread. 57: * 58: * <p>Threads have names to identify them. These names are not necessarily 59: * unique. Every Thread has a priority, as well, which tells the VM which 60: * Threads should get more running time. New threads inherit the priority 61: * and daemon status of the parent thread, by default. 62: * 63: * <p>There are two methods of creating a Thread: you may subclass Thread and 64: * implement the <code>run()</code> method, at which point you may start the 65: * Thread by calling its <code>start()</code> method, or you may implement 66: * <code>Runnable</code> in the class you want to use and then call new 67: * <code>Thread(your_obj).start()</code>. 68: * 69: * <p>The virtual machine runs until all non-daemon threads have died (either 70: * by returning from the run() method as invoked by start(), or by throwing 71: * an uncaught exception); or until <code>System.exit</code> is called with 72: * adequate permissions. 73: * 74: * <p>It is unclear at what point a Thread should be added to a ThreadGroup, 75: * and at what point it should be removed. Should it be inserted when it 76: * starts, or when it is created? Should it be removed when it is suspended 77: * or interrupted? The only thing that is clear is that the Thread should be 78: * removed when it is stopped. 79: * 80: * @author Tom Tromey 81: * @author John Keiser 82: * @author Eric Blake (ebb9@email.byu.edu) 83: * @see Runnable 84: * @see Runtime#exit(int) 85: * @see #run() 86: * @see #start() 87: * @see ThreadLocal 88: * @since 1.0 89: * @status updated to 1.4 90: */ 91: public class Thread implements Runnable 92: { 93: /** The minimum priority for a Thread. */ 94: public static final int MIN_PRIORITY = 1; 95: 96: /** The priority a Thread gets by default. */ 97: public static final int NORM_PRIORITY = 5; 98: 99: /** The maximum priority for a Thread. */ 100: public static final int MAX_PRIORITY = 10; 101: 102: /** The underlying VM thread, only set when the thread is actually running. 103: */ 104: volatile VMThread vmThread; 105: 106: /** 107: * The group this thread belongs to. This is set to null by 108: * ThreadGroup.removeThread when the thread dies. 109: */ 110: volatile ThreadGroup group; 111: 112: /** The object to run(), null if this is the target. */ 113: final Runnable runnable; 114: 115: /** The thread name, non-null. */ 116: volatile String name; 117: 118: /** Whether the thread is a daemon. */ 119: volatile boolean daemon; 120: 121: /** The thread priority, 1 to 10. */ 122: volatile int priority; 123: 124: /** Native thread stack size. 0 = use default */ 125: private long stacksize; 126: 127: /** Was the thread stopped before it was started? */ 128: Throwable stillborn; 129: 130: /** The context classloader for this Thread. */ 131: private ClassLoader contextClassLoader; 132: 133: /** The next thread number to use. */ 134: private static int numAnonymousThreadsCreated; 135: 136: /** Thread local storage. Package accessible for use by 137: * InheritableThreadLocal. 138: */ 139: WeakHashMap locals; 140: 141: /** 142: * Allocates a new <code>Thread</code> object. This constructor has 143: * the same effect as <code>Thread(null, null,</code> 144: * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is 145: * a newly generated name. Automatically generated names are of the 146: * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. 147: * <p> 148: * Threads created this way must have overridden their 149: * <code>run()</code> method to actually do anything. An example 150: * illustrating this method being used follows: 151: * <p><blockquote><pre> 152: * import java.lang.*; 153: * 154: * class plain01 implements Runnable { 155: * String name; 156: * plain01() { 157: * name = null; 158: * } 159: * plain01(String s) { 160: * name = s; 161: * } 162: * public void run() { 163: * if (name == null) 164: * System.out.println("A new thread created"); 165: * else 166: * System.out.println("A new thread with name " + name + 167: * " created"); 168: * } 169: * } 170: * class threadtest01 { 171: * public static void main(String args[] ) { 172: * int failed = 0 ; 173: * 174: * <b>Thread t1 = new Thread();</b> 175: * if (t1 != null) 176: * System.out.println("new Thread() succeed"); 177: * else { 178: * System.out.println("new Thread() failed"); 179: * failed++; 180: * } 181: * } 182: * } 183: * </pre></blockquote> 184: * 185: * @see java.lang.Thread#Thread(java.lang.ThreadGroup, 186: * java.lang.Runnable, java.lang.String) 187: */ 188: public Thread() 189: { 190: this(null, (Runnable) null); 191: } 192: 193: /** 194: * Allocates a new <code>Thread</code> object. This constructor has 195: * the same effect as <code>Thread(null, target,</code> 196: * <i>gname</i><code>)</code>, where <i>gname</i> is 197: * a newly generated name. Automatically generated names are of the 198: * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. 199: * 200: * @param target the object whose <code>run</code> method is called. 201: * @see java.lang.Thread#Thread(java.lang.ThreadGroup, 202: * java.lang.Runnable, java.lang.String) 203: */ 204: public Thread(Runnable target) 205: { 206: this(null, target); 207: } 208: 209: /** 210: * Allocates a new <code>Thread</code> object. This constructor has 211: * the same effect as <code>Thread(null, null, name)</code>. 212: * 213: * @param name the name of the new thread. 214: * @see java.lang.Thread#Thread(java.lang.ThreadGroup, 215: * java.lang.Runnable, java.lang.String) 216: */ 217: public Thread(String name) 218: { 219: this(null, null, name, 0); 220: } 221: 222: /** 223: * Allocates a new <code>Thread</code> object. This constructor has 224: * the same effect as <code>Thread(group, target,</code> 225: * <i>gname</i><code>)</code>, where <i>gname</i> is 226: * a newly generated name. Automatically generated names are of the 227: * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. 228: * 229: * @param group the group to put the Thread into 230: * @param target the Runnable object to execute 231: * @throws SecurityException if this thread cannot access <code>group</code> 232: * @throws IllegalThreadStateException if group is destroyed 233: * @see #Thread(ThreadGroup, Runnable, String) 234: */ 235: public Thread(ThreadGroup group, Runnable target) 236: { 237: this(group, target, "Thread-" + ++numAnonymousThreadsCreated, 0); 238: } 239: 240: /** 241: * Allocates a new <code>Thread</code> object. This constructor has 242: * the same effect as <code>Thread(group, null, name)</code> 243: * 244: * @param group the group to put the Thread into 245: * @param name the name for the Thread 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: * @see #Thread(ThreadGroup, Runnable, String) 250: */ 251: public Thread(ThreadGroup group, String name) 252: { 253: this(group, null, name, 0); 254: } 255: 256: /** 257: * Allocates a new <code>Thread</code> object. This constructor has 258: * the same effect as <code>Thread(null, target, name)</code>. 259: * 260: * @param target the Runnable object to execute 261: * @param name the name for the Thread 262: * @throws NullPointerException if name is null 263: * @see #Thread(ThreadGroup, Runnable, String) 264: */ 265: public Thread(Runnable target, String name) 266: { 267: this(null, target, name, 0); 268: } 269: 270: /** 271: * Allocate a new Thread object, with the specified ThreadGroup and name, and 272: * using the specified Runnable object's <code>run()</code> method to 273: * execute. If the Runnable object is null, <code>this</code> (which is 274: * a Runnable) is used instead. 275: * 276: * <p>If the ThreadGroup is null, the security manager is checked. If a 277: * manager exists and returns a non-null object for 278: * <code>getThreadGroup</code>, that group is used; otherwise the group 279: * of the creating thread is used. Note that the security manager calls 280: * <code>checkAccess</code> if the ThreadGroup is not null. 281: * 282: * <p>The new Thread will inherit its creator's priority and daemon status. 283: * These can be changed with <code>setPriority</code> and 284: * <code>setDaemon</code>. 285: * 286: * @param group the group to put the Thread into 287: * @param target the Runnable object to execute 288: * @param name the name for the Thread 289: * @throws NullPointerException if name is null 290: * @throws SecurityException if this thread cannot access <code>group</code> 291: * @throws IllegalThreadStateException if group is destroyed 292: * @see Runnable#run() 293: * @see #run() 294: * @see #setDaemon(boolean) 295: * @see #setPriority(int) 296: * @see SecurityManager#checkAccess(ThreadGroup) 297: * @see ThreadGroup#checkAccess() 298: */ 299: public Thread(ThreadGroup group, Runnable target, String name) 300: { 301: this(group, target, name, 0); 302: } 303: 304: /** 305: * Allocate a new Thread object, as if by 306: * <code>Thread(group, null, name)</code>, and give it the specified stack 307: * size, in bytes. The stack size is <b>highly platform independent</b>, 308: * and the virtual machine is free to round up or down, or ignore it 309: * completely. A higher value might let you go longer before a 310: * <code>StackOverflowError</code>, while a lower value might let you go 311: * longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely 312: * nothing! So be careful, and expect to need to tune this value if your 313: * virtual machine even supports it. 314: * 315: * @param group the group to put the Thread into 316: * @param target the Runnable object to execute 317: * @param name the name for the Thread 318: * @param size the stack size, in bytes; 0 to be ignored 319: * @throws NullPointerException if name is null 320: * @throws SecurityException if this thread cannot access <code>group</code> 321: * @throws IllegalThreadStateException if group is destroyed 322: * @since 1.4 323: */ 324: public Thread(ThreadGroup group, Runnable target, String name, long size) 325: { 326: // Bypass System.getSecurityManager, for bootstrap efficiency. 327: SecurityManager sm = SecurityManager.current; 328: Thread current = currentThread(); 329: if (group == null) 330: { 331: if (sm != null) 332: group = sm.getThreadGroup(); 333: if (group == null) 334: group = current.group; 335: } 336: else if (sm != null) 337: sm.checkAccess(group); 338: 339: this.group = group; 340: // Use toString hack to detect null. 341: this.name = name.toString(); 342: this.runnable = target; 343: this.stacksize = size; 344: 345: priority = current.priority; 346: daemon = current.daemon; 347: contextClassLoader = current.contextClassLoader; 348: 349: group.addThread(this); 350: InheritableThreadLocal.newChildThread(this); 351: } 352: 353: /** 354: * Used by the VM to create thread objects for threads started outside 355: * of Java. Note: caller is responsible for adding the thread to 356: * a group and InheritableThreadLocal. 357: * 358: * @param vmThread the native thread 359: * @param name the thread name or null to use the default naming scheme 360: * @param priority current priority 361: * @param daemon is the thread a background thread? 362: */ 363: Thread(VMThread vmThread, String name, int priority, boolean daemon) 364: { 365: this.vmThread = vmThread; 366: this.runnable = null; 367: if (name == null) 368: name = "Thread-" + ++numAnonymousThreadsCreated; 369: this.name = name; 370: this.priority = priority; 371: this.daemon = daemon; 372: this.contextClassLoader = ClassLoader.getSystemClassLoader(); 373: } 374: 375: /** 376: * Get the number of active threads in the current Thread's ThreadGroup. 377: * This implementation calls 378: * <code>currentThread().getThreadGroup().activeCount()</code>. 379: * 380: * @return the number of active threads in the current ThreadGroup 381: * @see ThreadGroup#activeCount() 382: */ 383: public static int activeCount() 384: { 385: return currentThread().group.activeCount(); 386: } 387: 388: /** 389: * Check whether the current Thread is allowed to modify this Thread. This 390: * passes the check on to <code>SecurityManager.checkAccess(this)</code>. 391: * 392: * @throws SecurityException if the current Thread cannot modify this Thread 393: * @see SecurityManager#checkAccess(Thread) 394: */ 395: public final void checkAccess() 396: { 397: // Bypass System.getSecurityManager, for bootstrap efficiency. 398: SecurityManager sm = SecurityManager.current; 399: if (sm != null) 400: sm.checkAccess(this); 401: } 402: 403: /** 404: * Count the number of stack frames in this Thread. The Thread in question 405: * must be suspended when this occurs. 406: * 407: * @return the number of stack frames in this Thread 408: * @throws IllegalThreadStateException if this Thread is not suspended 409: * @deprecated pointless, since suspend is deprecated 410: */ 411: public int countStackFrames() 412: { 413: VMThread t = vmThread; 414: if (t == null || group == null) 415: throw new IllegalThreadStateException(); 416: 417: return t.countStackFrames(); 418: } 419: 420: /** 421: * Get the currently executing Thread. In the situation that the 422: * currently running thread was created by native code and doesn't 423: * have an associated Thread object yet, a new Thread object is 424: * constructed and associated with the native thread. 425: * 426: * @return the currently executing Thread 427: */ 428: public static Thread currentThread() 429: { 430: return VMThread.currentThread(); 431: } 432: 433: /** 434: * Originally intended to destroy this thread, this method was never 435: * implemented by Sun, and is hence a no-op. 436: */ 437: public void destroy() 438: { 439: throw new NoSuchMethodError(); 440: } 441: 442: /** 443: * Print a stack trace of the current thread to stderr using the same 444: * format as Throwable's printStackTrace() method. 445: * 446: * @see Throwable#printStackTrace() 447: */ 448: public static void dumpStack() 449: { 450: new Throwable().printStackTrace(); 451: } 452: 453: /** 454: * Copy every active thread in the current Thread's ThreadGroup into the 455: * array. Extra threads are silently ignored. This implementation calls 456: * <code>getThreadGroup().enumerate(array)</code>, which may have a 457: * security check, <code>checkAccess(group)</code>. 458: * 459: * @param array the array to place the Threads into 460: * @return the number of Threads placed into the array 461: * @throws NullPointerException if array is null 462: * @throws SecurityException if you cannot access the ThreadGroup 463: * @see ThreadGroup#enumerate(Thread[]) 464: * @see #activeCount() 465: * @see SecurityManager#checkAccess(ThreadGroup) 466: */ 467: public static int enumerate(Thread[] array) 468: { 469: return currentThread().group.enumerate(array); 470: } 471: 472: /** 473: * Get this Thread's name. 474: * 475: * @return this Thread's name 476: */ 477: public final String getName() 478: { 479: VMThread t = vmThread; 480: return t == null ? name : t.getName(); 481: } 482: 483: /** 484: * Get this Thread's priority. 485: * 486: * @return the Thread's priority 487: */ 488: public final synchronized int getPriority() 489: { 490: VMThread t = vmThread; 491: return t == null ? priority : t.getPriority(); 492: } 493: 494: /** 495: * Get the ThreadGroup this Thread belongs to. If the thread has died, this 496: * returns null. 497: * 498: * @return this Thread's ThreadGroup 499: */ 500: public final ThreadGroup getThreadGroup() 501: { 502: return group; 503: } 504: 505: /** 506: * Checks whether the current thread holds the monitor on a given object. 507: * This allows you to do <code>assert Thread.holdsLock(obj)</code>. 508: * 509: * @param obj the object to test lock ownership on. 510: * @return true if the current thread is currently synchronized on obj 511: * @throws NullPointerException if obj is null 512: * @since 1.4 513: */ 514: public static boolean holdsLock(Object obj) 515: { 516: return VMThread.holdsLock(obj); 517: } 518: 519: /** 520: * Interrupt this Thread. First, there is a security check, 521: * <code>checkAccess</code>. Then, depending on the current state of the 522: * thread, various actions take place: 523: * 524: * <p>If the thread is waiting because of {@link #wait()}, 525: * {@link #sleep(long)}, or {@link #join()}, its <i>interrupt status</i> 526: * will be cleared, and an InterruptedException will be thrown. Notice that 527: * this case is only possible if an external thread called interrupt(). 528: * 529: * <p>If the thread is blocked in an interruptible I/O operation, in 530: * {@link java.nio.channels.InterruptibleChannel}, the <i>interrupt 531: * status</i> will be set, and ClosedByInterruptException will be thrown. 532: * 533: * <p>If the thread is blocked on a {@link java.nio.channels.Selector}, the 534: * <i>interrupt status</i> will be set, and the selection will return, with 535: * a possible non-zero value, as though by the wakeup() method. 536: * 537: * <p>Otherwise, the interrupt status will be set. 538: * 539: * @throws SecurityException if you cannot modify this Thread 540: */ 541: public synchronized void interrupt() 542: { 543: checkAccess(); 544: VMThread t = vmThread; 545: if (t != null) 546: t.interrupt(); 547: } 548: 549: /** 550: * Determine whether the current Thread has been interrupted, and clear 551: * the <i>interrupted status</i> in the process. 552: * 553: * @return whether the current Thread has been interrupted 554: * @see #isInterrupted() 555: */ 556: public static boolean interrupted() 557: { 558: return VMThread.interrupted(); 559: } 560: 561: /** 562: * Determine whether the given Thread has been interrupted, but leave 563: * the <i>interrupted status</i> alone in the process. 564: * 565: * @return whether the Thread has been interrupted 566: * @see #interrupted() 567: */ 568: public boolean isInterrupted() 569: { 570: VMThread t = vmThread; 571: return t != null && t.isInterrupted(); 572: } 573: 574: /** 575: * Determine whether this Thread is alive. A thread which is alive has 576: * started and not yet died. 577: * 578: * @return whether this Thread is alive 579: */ 580: public final boolean isAlive() 581: { 582: return vmThread != null && group != null; 583: } 584: 585: /** 586: * Tell whether this is a daemon Thread or not. 587: * 588: * @return whether this is a daemon Thread or not 589: * @see #setDaemon(boolean) 590: */ 591: public final boolean isDaemon() 592: { 593: VMThread t = vmThread; 594: return t == null ? daemon : t.isDaemon(); 595: } 596: 597: /** 598: * Wait forever for the Thread in question to die. 599: * 600: * @throws InterruptedException if the Thread is interrupted; it's 601: * <i>interrupted status</i> will be cleared 602: */ 603: public final void join() throws InterruptedException 604: { 605: join(0, 0); 606: } 607: 608: /** 609: * Wait the specified amount of time for the Thread in question to die. 610: * 611: * @param ms the number of milliseconds to wait, or 0 for forever 612: * @throws InterruptedException if the Thread is interrupted; it's 613: * <i>interrupted status</i> will be cleared 614: */ 615: public final void join(long ms) throws InterruptedException 616: { 617: join(ms, 0); 618: } 619: 620: /** 621: * Wait the specified amount of time for the Thread in question to die. 622: * 623: * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do 624: * not offer that fine a grain of timing resolution. Besides, there is 625: * no guarantee that this thread can start up immediately when time expires, 626: * because some other thread may be active. So don't expect real-time 627: * performance. 628: * 629: * @param ms the number of milliseconds to wait, or 0 for forever 630: * @param ns the number of extra nanoseconds to sleep (0-999999) 631: * @throws InterruptedException if the Thread is interrupted; it's 632: * <i>interrupted status</i> will be cleared 633: * @throws IllegalArgumentException if ns is invalid 634: */ 635: public final void join(long ms, int ns) throws InterruptedException 636: { 637: if(ms < 0 || ns < 0 || ns > 999999) 638: throw new IllegalArgumentException(); 639: 640: VMThread t = vmThread; 641: if(t != null) 642: t.join(ms, ns); 643: } 644: 645: /** 646: * Resume this Thread. If the thread is not suspended, this method does 647: * nothing. To mirror suspend(), there may be a security check: 648: * <code>checkAccess</code>. 649: * 650: * @throws SecurityException if you cannot resume the Thread 651: * @see #checkAccess() 652: * @see #suspend() 653: * @deprecated pointless, since suspend is deprecated 654: */ 655: public final synchronized void resume() 656: { 657: checkAccess(); 658: VMThread t = vmThread; 659: if (t != null) 660: t.resume(); 661: } 662: 663: /** 664: * The method of Thread that will be run if there is no Runnable object 665: * associated with the Thread. Thread's implementation does nothing at all. 666: * 667: * @see #start() 668: * @see #Thread(ThreadGroup, Runnable, String) 669: */ 670: public void run() 671: { 672: if (runnable != null) 673: runnable.run(); 674: } 675: 676: /** 677: * Set the daemon status of this Thread. If this is a daemon Thread, then 678: * the VM may exit even if it is still running. This may only be called 679: * before the Thread starts running. There may be a security check, 680: * <code>checkAccess</code>. 681: * 682: * @param daemon whether this should be a daemon thread or not 683: * @throws SecurityException if you cannot modify this Thread 684: * @throws IllegalThreadStateException if the Thread is active 685: * @see #isDaemon() 686: * @see #checkAccess() 687: */ 688: public final synchronized void setDaemon(boolean daemon) 689: { 690: if (vmThread != null) 691: throw new IllegalThreadStateException(); 692: checkAccess(); 693: this.daemon = daemon; 694: } 695: 696: /** 697: * Returns the context classloader of this Thread. The context 698: * classloader can be used by code that want to load classes depending 699: * on the current thread. Normally classes are loaded depending on 700: * the classloader of the current class. There may be a security check 701: * for <code>RuntimePermission("getClassLoader")</code> if the caller's 702: * class loader is not null or an ancestor of this thread's context class 703: * loader. 704: * 705: * @return the context class loader 706: * @throws SecurityException when permission is denied 707: * @see setContextClassLoader(ClassLoader) 708: * @since 1.2 709: */ 710: public synchronized ClassLoader getContextClassLoader() 711: { 712: // Bypass System.getSecurityManager, for bootstrap efficiency. 713: SecurityManager sm = SecurityManager.current; 714: if (sm != null) 715: // XXX Don't check this if the caller's class loader is an ancestor. 716: sm.checkPermission(new RuntimePermission("getClassLoader")); 717: return contextClassLoader; 718: } 719: 720: /** 721: * Sets the context classloader for this Thread. When not explicitly set, 722: * the context classloader for a thread is the same as the context 723: * classloader of the thread that created this thread. The first thread has 724: * as context classloader the system classloader. There may be a security 725: * check for <code>RuntimePermission("setContextClassLoader")</code>. 726: * 727: * @param classloader the new context class loader 728: * @throws SecurityException when permission is denied 729: * @see getContextClassLoader() 730: * @since 1.2 731: */ 732: public synchronized void setContextClassLoader(ClassLoader classloader) 733: { 734: SecurityManager sm = SecurityManager.current; 735: if (sm != null) 736: sm.checkPermission(new RuntimePermission("setContextClassLoader")); 737: this.contextClassLoader = classloader; 738: } 739: 740: /** 741: * Set this Thread's name. There may be a security check, 742: * <code>checkAccess</code>. 743: * 744: * @param name the new name for this Thread 745: * @throws NullPointerException if name is null 746: * @throws SecurityException if you cannot modify this Thread 747: */ 748: public final synchronized void setName(String name) 749: { 750: checkAccess(); 751: // The Class Libraries book says ``threadName cannot be null''. I 752: // take this to mean NullPointerException. 753: if (name == null) 754: throw new NullPointerException(); 755: VMThread t = vmThread; 756: if (t != null) 757: t.setName(name); 758: else 759: this.name = name; 760: } 761: 762: /** 763: * Yield to another thread. The Thread will not lose any locks it holds 764: * during this time. There are no guarantees which thread will be 765: * next to run, and it could even be this one, but most VMs will choose 766: * the highest priority thread that has been waiting longest. 767: */ 768: public static void yield() 769: { 770: VMThread.yield(); 771: } 772: 773: /** 774: * Suspend the current Thread's execution for the specified amount of 775: * time. The Thread will not lose any locks it has during this time. There 776: * are no guarantees which thread will be next to run, but most VMs will 777: * choose the highest priority thread that has been waiting longest. 778: * 779: * @param ms the number of milliseconds to sleep. 780: * @throws InterruptedException if the Thread is (or was) interrupted; 781: * it's <i>interrupted status</i> will be cleared 782: * @throws IllegalArgumentException if ms is negative 783: * @see #interrupt() 784: */ 785: public static void sleep(long ms) throws InterruptedException 786: { 787: sleep(ms, 0); 788: } 789: 790: /** 791: * Suspend the current Thread's execution for the specified amount of 792: * time. The Thread will not lose any locks it has during this time. There 793: * are no guarantees which thread will be next to run, but most VMs will 794: * choose the highest priority thread that has been waiting longest. 795: * <p> 796: * Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs 797: * do not offer that fine a grain of timing resolution. When ms is 798: * zero and ns is non-zero the Thread will sleep for at least one 799: * milli second. There is no guarantee that this thread can start up 800: * immediately when time expires, because some other thread may be 801: * active. So don't expect real-time performance. 802: * 803: * @param ms the number of milliseconds to sleep 804: * @param ns the number of extra nanoseconds to sleep (0-999999) 805: * @throws InterruptedException if the Thread is (or was) interrupted; 806: * it's <i>interrupted status</i> will be cleared 807: * @throws IllegalArgumentException if ms or ns is negative 808: * or ns is larger than 999999. 809: * @see #interrupt() 810: */ 811: public static void sleep(long ms, int ns) throws InterruptedException 812: { 813: 814: // Check parameters 815: if (ms < 0 || ns < 0 || ns > 999999) 816: throw new IllegalArgumentException(); 817: 818: // Really sleep 819: VMThread.sleep(ms, ns); 820: } 821: 822: /** 823: * Start this Thread, calling the run() method of the Runnable this Thread 824: * was created with, or else the run() method of the Thread itself. This 825: * is the only way to start a new thread; calling run by yourself will just 826: * stay in the same thread. The virtual machine will remove the thread from 827: * its thread group when the run() method completes. 828: * 829: * @throws IllegalThreadStateException if the thread has already started 830: * @see #run() 831: */ 832: public synchronized void start() 833: { 834: if (vmThread != null || group == null) 835: throw new IllegalThreadStateException(); 836: 837: VMThread.create(this, stacksize); 838: } 839: 840: /** 841: * Cause this Thread to stop abnormally because of the throw of a ThreadDeath 842: * error. If you stop a Thread that has not yet started, it will stop 843: * immediately when it is actually started. 844: * 845: * <p>This is inherently unsafe, as it can interrupt synchronized blocks and 846: * leave data in bad states. Hence, there is a security check: 847: * <code>checkAccess(this)</code>, plus another one if the current thread 848: * is not this: <code>RuntimePermission("stopThread")</code>. If you must 849: * catch a ThreadDeath, be sure to rethrow it after you have cleaned up. 850: * ThreadDeath is the only exception which does not print a stack trace when 851: * the thread dies. 852: * 853: * @throws SecurityException if you cannot stop the Thread 854: * @see #interrupt() 855: * @see #checkAccess() 856: * @see #start() 857: * @see ThreadDeath 858: * @see ThreadGroup#uncaughtException(Thread, Throwable) 859: * @see SecurityManager#checkAccess(Thread) 860: * @see SecurityManager#checkPermission(Permission) 861: * @deprecated unsafe operation, try not to use 862: */ 863: public final void stop() 864: { 865: stop(new ThreadDeath()); 866: } 867: 868: /** 869: * Cause this Thread to stop abnormally and throw the specified exception. 870: * If you stop a Thread that has not yet started, the stop is ignored 871: * (contrary to what the JDK documentation says). 872: * <b>WARNING</b>This bypasses Java security, and can throw a checked 873: * exception which the call stack is unprepared to handle. Do not abuse 874: * this power. 875: * 876: * <p>This is inherently unsafe, as it can interrupt synchronized blocks and 877: * leave data in bad states. Hence, there is a security check: 878: * <code>checkAccess(this)</code>, plus another one if the current thread 879: * is not this: <code>RuntimePermission("stopThread")</code>. If you must 880: * catch a ThreadDeath, be sure to rethrow it after you have cleaned up. 881: * ThreadDeath is the only exception which does not print a stack trace when 882: * the thread dies. 883: * 884: * @param t the Throwable to throw when the Thread dies 885: * @throws SecurityException if you cannot stop the Thread 886: * @throws NullPointerException in the calling thread, if t is null 887: * @see #interrupt() 888: * @see #checkAccess() 889: * @see #start() 890: * @see ThreadDeath 891: * @see ThreadGroup#uncaughtException(Thread, Throwable) 892: * @see SecurityManager#checkAccess(Thread) 893: * @see SecurityManager#checkPermission(Permission) 894: * @deprecated unsafe operation, try not to use 895: */ 896: public final synchronized void stop(Throwable t) 897: { 898: if (t == null) 899: throw new NullPointerException(); 900: // Bypass System.getSecurityManager, for bootstrap efficiency. 901: SecurityManager sm = SecurityManager.current; 902: if (sm != null) 903: { 904: sm.checkAccess(this); 905: if (this != currentThread()) 906: sm.checkPermission(new RuntimePermission("stopThread")); 907: } 908: VMThread vt = vmThread; 909: if (vt != null) 910: vt.stop(t); 911: else 912: stillborn = t; 913: } 914: 915: /** 916: * Suspend this Thread. It will not come back, ever, unless it is resumed. 917: * 918: * <p>This is inherently unsafe, as the suspended thread still holds locks, 919: * and can potentially deadlock your program. Hence, there is a security 920: * check: <code>checkAccess</code>. 921: * 922: * @throws SecurityException if you cannot suspend the Thread 923: * @see #checkAccess() 924: * @see #resume() 925: * @deprecated unsafe operation, try not to use 926: */ 927: public final synchronized void suspend() 928: { 929: checkAccess(); 930: VMThread t = vmThread; 931: if (t != null) 932: t.suspend(); 933: } 934: 935: /** 936: * Set this Thread's priority. There may be a security check, 937: * <code>checkAccess</code>, then the priority is set to the smaller of 938: * priority and the ThreadGroup maximum priority. 939: * 940: * @param priority the new priority for this Thread 941: * @throws IllegalArgumentException if priority exceeds MIN_PRIORITY or 942: * MAX_PRIORITY 943: * @throws SecurityException if you cannot modify this Thread 944: * @see #getPriority() 945: * @see #checkAccess() 946: * @see ThreadGroup#getMaxPriority() 947: * @see #MIN_PRIORITY 948: * @see #MAX_PRIORITY 949: */ 950: public final synchronized void setPriority(int priority) 951: { 952: checkAccess(); 953: if (priority < MIN_PRIORITY || priority > MAX_PRIORITY) 954: throw new IllegalArgumentException("Invalid thread priority value " 955: + priority + "."); 956: priority = Math.min(priority, group.getMaxPriority()); 957: VMThread t = vmThread; 958: if (t != null) 959: t.setPriority(priority); 960: else 961: this.priority = priority; 962: } 963: 964: /** 965: * Returns a string representation of this thread, including the 966: * thread's name, priority, and thread group. 967: * 968: * @return a human-readable String representing this Thread 969: */ 970: public String toString() 971: { 972: return ("Thread[" + name + "," + priority + "," 973: + (group == null ? "" : group.getName()) + "]"); 974: } 975: 976: /** 977: * Clean up code, called by VMThread when thread dies. 978: */ 979: synchronized void die() 980: { 981: group.removeThread(this); 982: vmThread = null; 983: locals = null; 984: } 985: 986: /** 987: * Returns the map used by ThreadLocal to store the thread local values. 988: */ 989: static Map getThreadLocals() 990: { 991: Thread thread = currentThread(); 992: Map locals = thread.locals; 993: if (locals == null) 994: { 995: locals = thread.locals = new WeakHashMap(); 996: } 997: return locals; 998: } 999: }
GNU Classpath (0.17) |