home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / solaris2 / jdk / src / java / lang / thread.jav < prev    next >
Encoding:
Text File  |  1995-10-30  |  16.2 KB  |  565 lines

  1. /*
  2.  * @(#)Thread.java    1.43 95/09/22  
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.lang;
  21.  
  22. /**
  23.  * A Thread is a single sequential flow of control within a process. This simply means
  24.  * that while executing within a program, each thread has a beginning, a sequence, a 
  25.  * point of execution occurring at any time during runtime of the thread and of course, an ending. 
  26.  * Thread objects are the basis for multi-threaded programming.  Multi-threaded programming
  27.  * allows a single program to conduct concurrently running threads that perform different tasks.
  28.  * <p>
  29.  * To create a new thread of execution, declare a new class which is a
  30.  * subclass of Thread and then override the run() method with code that you
  31.  * want executed in this Thread.  An instance of the Thread subclass should be created next
  32.  * with a call to the start() method following the instance.  The start() method will create the 
  33.  * thread and execute the run() method. 
  34.  * For example:<p>
  35.  * <pre>
  36.  *    class PrimeThread extends Thread {
  37.  *        public void run() {
  38.  *        // compute primes...
  39.  *        }
  40.  *    }
  41.  * </pre>
  42.  * To start this thread you need to do the following:
  43.  * <pre>
  44.  *    PrimeThread p = new PrimeThread();
  45.  *    p.start();
  46.  *    ...
  47.  * </pre>
  48.  * Another way to create a thread is by using the Runnable interface.
  49.  * This way any object that implements the Runnable interface can be
  50.  * run in a thread. For example:
  51.  * <pre>
  52.  *    class Primes implements Runnable {
  53.  *        public void run() {
  54.  *        // compute primes...
  55.  *        }
  56.  *    }
  57.  * </pre>
  58.  * To start this thread you need to do the following:
  59.  * <pre>
  60.  *    Primes p = new Primes();
  61.  *    new Thread(p).start();
  62.  *    ...
  63.  * </pre>
  64.  * The virtual machine runs until all Threads that are not daemon Threads
  65.  * have died. A Thread dies when its run() method returns, or when the
  66.  * stop() method is called.
  67.  * <p>
  68.  * When a new Thread is created, it inherits the priority and the
  69.  * daemon flag from its parent (i.e.: the Thread that created it).
  70.  * @see Runnable
  71.  * @version     1.43, 09/22/95
  72.  */
  73. public
  74. class Thread implements Runnable {
  75.     private char    name[];
  76.     private int         priority;
  77.     private Thread    threadQ;
  78.     private int     PrivateInfo;
  79.     private int        eetop;
  80.  
  81.     /* Whether or not to single_step this thread. */
  82.     private boolean    single_step;
  83.  
  84.     /* Whether or not the thread is a daemon thread. */
  85.     private boolean    daemon = false;
  86.  
  87.     /* Whether or not this thread was asked to exit before it runs.*/
  88.     private boolean    stillborn = false;
  89.  
  90.     /* What will be run. */
  91.     private Runnable target;
  92.  
  93.     /* The system queue of threads is linked through activeThreadQueue. */
  94.     private static Thread activeThreadQ;
  95.  
  96.     /* The group of this thread */
  97.     private ThreadGroup group;
  98.  
  99.     /* For autonumbering anonymous threads. */
  100.     private static int threadInitNumber;
  101.     private static synchronized int nextThreadNum() {
  102.     return threadInitNumber++;
  103.     }
  104.  
  105.     /**
  106.      * The minimum priority that a Thread can have.  The most minimal priority is equal to 1.      
  107.      */
  108.     public final static int MIN_PRIORITY = 1;
  109.  
  110.     /**
  111.      * The default priority that is assigned to a Thread.  The default priority is equal to 5.
  112.      */
  113.     public final static int NORM_PRIORITY = 5;
  114.  
  115.     /**
  116.      * The maximum priority that a Thread can have.  The maximal priority value a Thread can have is 10.
  117.      */
  118.     public final static int MAX_PRIORITY = 10;
  119.  
  120.     /**
  121.      * Returns a reference to the currently executing Thread object.
  122.      */
  123.     public static native Thread currentThread();
  124.  
  125.     /**
  126.      * Causes the currently executing Thread object to yield.
  127.      * If there are other runnable Threads they will be
  128.      * scheduled next.
  129.      */
  130.     public static native void yield();
  131.  
  132.     /**    
  133.      * Causes the currently executing Thread to sleep for the specified
  134.      * number of milliseconds.
  135.      * @param millis  the length of time to sleep in milliseconds
  136.      */
  137.     public static native void sleep(long millis) throws InterruptedException;
  138.  
  139.     /**
  140.      * Sleep, in milliseconds and additional nanosecond.
  141.      * @param millis  the length of time to sleep in milliseconds
  142.      * @param nanos   0-999999 additional nanoseconds to sleep
  143.      */
  144.     public static void sleep(long millis, int nanos) throws InterruptedException {
  145.     if (nanos > 500000)
  146.         millis++;
  147.     sleep(millis);
  148.     }
  149.  
  150.     /**
  151.      * Initialize a Thread.
  152.      * @param g the Thread group
  153.      * @param target the object whose run() method gets called
  154.      * @param name the name of the new Thread
  155.      */
  156.     private void init(ThreadGroup g, Runnable target, String name){
  157.     Thread parent = currentThread();
  158.     if (g == null) {
  159.         g = parent.getThreadGroup();
  160.     } else {
  161.         g.checkAccess();
  162.     }
  163.     this.group = g;
  164.     this.daemon = parent.isDaemon();
  165.     this.priority = parent.getPriority();
  166.     this.name = name.toCharArray();
  167.     this.target = target;
  168.     setPriority0(priority);
  169.     g.add(this);
  170.     }
  171.  
  172.     /**
  173.      * Constructs a new Thread. Threads created this way must have
  174.      * overridden their run() method to actually do anything.  An example
  175.      * illustrating this method being used is shown.
  176.      * <p><pre>
  177.      * import java.lang.*; 
  178.      * <p>
  179.      * class plain01 implements Runnable {
  180.      *   String name; 
  181.      *   plain01() {
  182.      *     name = null;
  183.      *   }
  184.      *   plain01(String s) {
  185.      *     name = s;
  186.      *   }
  187.      *   public void run() {
  188.      *     if (name == null)
  189.      *       System.out.println("A new thread created");
  190.      *     else
  191.      *       System.out.println("A new thread with name " + name + " created");
  192.      *   }
  193.      * }<p>
  194.      * class threadtest01 {
  195.      *   public static void main(String args[] ) {
  196.      *     int failed = 0 ;
  197.      * <p>
  198.      * <b>   Thread t1 = new Thread();</b>  
  199.      *     if(t1 != null) {
  200.      *       System.out.println("new Thread() succeed");
  201.      *     } else {
  202.      *        System.out.println("new Thread() failed"); 
  203.      *        failed++; 
  204.      *     } </pre>
  205.      * } <p>
  206.      */
  207.     public Thread() {
  208.     init(null, null, "Thread-" + nextThreadNum());
  209.     }
  210.  
  211.     /**
  212.      * Constructs a new Thread which applies the run() method of
  213.      * the specified target.  
  214.      * @param target    the object whose run() method is called
  215.      */
  216.     public Thread(Runnable target) {
  217.     init(null, target, "Thread-" + nextThreadNum());
  218.     }
  219.  
  220.     /**
  221.      * Constructs a new Thread in the specified Thread group that applies the run() method of
  222.      * the specified target. 
  223.      * @param group the Thread group
  224.      * @param target    the object whose run() method is called
  225.      */
  226.     public Thread(ThreadGroup group, Runnable target) {
  227.     init(group, target, "Thread-" + nextThreadNum());
  228.     }
  229.  
  230.     /**
  231.      * Constructs a new Thread with the specified name.  
  232.      * @param name    the name of the new Thread
  233.      */
  234.     public Thread(String name) {
  235.     init(null, null, name);
  236.     }
  237.  
  238.     /**
  239.      * Constructs a new Thread in the specified Thread group with the specified name.
  240.      * @param group the Thread group
  241.      * @param name    the name of the new Thread
  242.      */
  243.     public Thread(ThreadGroup group, String name) {
  244.     init(group, null, name);
  245.     }
  246.  
  247.     /**
  248.      * Constructs a new Thread with the specified name and applies
  249.      * the run() method of the specified target.  
  250.      * @param target    the object whose run() method is called
  251.      * @param name    the name of the new Thread
  252.      */
  253.     public Thread(Runnable target, String name) {
  254.     init(null, target, name);
  255.     }
  256.     /**
  257.      * Constructs a new Thread in the specified Thread group with the specified name and
  258.      * applies the run() method of the specified target.
  259.      * @param group the Thread group
  260.      * @param target the object whose run() method is called
  261.      * @param name the name of the new Thread
  262.      */
  263.     public Thread(ThreadGroup group, Runnable target, String name) {
  264.     init(group, target, name);
  265.     }
  266.  
  267.     /**
  268.      * Starts this Thread. This will cause the run() method to
  269.      * be called. This method will return immediately.
  270.      * @exception IllegalThreadStateException If the thread was already started.
  271.      * @see Thread#run
  272.      * @see Thread#stop
  273.      */
  274.     public synchronized native void start();
  275.  
  276.     /**
  277.      * The actual body of this Thread. This method is called after
  278.      * the Thread is started. You must either override this
  279.      * method by subclassing class Thread, or you must create
  280.      * the Thread with a Runnable target.
  281.      * @see Thread#start
  282.      * @see Thread#stop
  283.      */
  284.     public void run() {
  285.     if (target != null) {
  286.         target.run();
  287.     }
  288.     }
  289.  
  290.     /**
  291.      * This method is called by the system to give a Thread
  292.      * a chance to clean up before it actually exits.
  293.      */
  294.     private void exit() {
  295.     if (group != null) {
  296.         group.remove(this);
  297.         group = null;
  298.     }
  299.     }
  300.  
  301.     /** 
  302.      * Stops a Thread by tossing an object.  By default this
  303.      * routine tosses a new instance of ThreadDeath to the target
  304.      * Thread.  ThreadDeath is not actually a subclass of Exception,
  305.      * but is a subclass of Object.  Users should not normally try
  306.      * to catch ThreadDeath unless they must do some extraordinary
  307.      * cleanup operation.  If ThreadDeath is caught it is important
  308.      * to rethrow the object so that the thread will actually die.
  309.      * The top-level error handler will not print out a message if
  310.      * ThreadDeath falls through.
  311.      *
  312.      * @see Thread#start 
  313.      * @see Thread#run
  314.      */
  315.     public final void stop() {
  316.     stop(new ThreadDeath());
  317.     }
  318.  
  319.     /**
  320.      * Stops a Thread by tossing an object.  Normally, users should
  321.      * just call the stop() method without any argument.  However, in some
  322.      * exceptional circumstances used by the stop() method to kill a Thread,
  323.      * another object is tossed. ThreadDeath, is not actually a subclass
  324.      * of Exception, but is a subclass of Object.
  325.      * @param o the object to be tossed
  326.      * @see Thread#start 
  327.      * @see Thread#run 
  328.      */
  329.     public final synchronized void stop(Object o) {
  330.     checkAccess();
  331.     stop0(o);
  332.     }
  333.  
  334.     /**
  335.      * Send an interrupt to a thread.
  336.      */
  337.     public void interrupt() {
  338.     throw new NoSuchMethodError();
  339.     }
  340.  
  341.     /**
  342.      * Ask if you have been interrupted.
  343.      */
  344.     public static boolean interrupted() {
  345.     throw new NoSuchMethodError();
  346.     }
  347.  
  348.     /**
  349.      * Ask if another thread has been interrupted.
  350.      */
  351.     public boolean isInterrupted() {
  352.     throw new NoSuchMethodError();
  353.     }
  354.  
  355.     /**
  356.      * Destroy a thread, without any cleanup, i.e. just toss its state;
  357.      * any monitors it has locked remain locked.  A last resort.
  358.      */
  359.     public void destroy() {
  360.     throw new NoSuchMethodError();
  361.     }
  362.  
  363.     /**
  364.      * Returns a boolean indicating if the Thread is active.  Having an 
  365.      * active Thread means that the Thread has been started and has not
  366.      * been stopped.
  367.      */
  368.     public final native boolean isAlive();
  369.  
  370.     /**
  371.      * Suspends this Thread's execution.
  372.      */
  373.     public final void suspend() {
  374.     checkAccess();
  375.     suspend0();
  376.     }
  377.  
  378.     /**
  379.      * Resumes this Thread execution.  This method is only valid after suspend()
  380.      * has been invoked.
  381.      */
  382.     public final void resume() {
  383.     checkAccess();
  384.     resume0();
  385.     }
  386.  
  387.     /**
  388.      * Sets the Thread's priority.
  389.      * @exception IllegalArgumentException If the priority is not within the
  390.      *        range MIN_PRIORITY, MAX_PRIORITY.
  391.      * @see Thread#MIN_PRIORITY
  392.      * @see Thread#MAX_PRIORITY
  393.      * @see Thread#getPriority
  394.      */
  395.     public final void setPriority(int newPriority) {
  396.     checkAccess();
  397.     if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
  398.         throw new IllegalArgumentException();
  399.     }
  400.     if (newPriority > group.getMaxPriority()) {
  401.         newPriority = group.getMaxPriority();
  402.     }
  403.     setPriority0(priority = newPriority);
  404.     }
  405.  
  406.     /**
  407.      * Gets and returns the Thread's priority.
  408.      * @see Thread#setPriority
  409.      */
  410.     public final int getPriority() {
  411.     return priority;
  412.     }
  413.  
  414.     /**
  415.      * Sets the Thread's name.
  416.      * @param name    the new name of the Thread
  417.      * @see Thread#getName
  418.      */
  419.     public final void setName(String name) {
  420.     checkAccess();
  421.     this.name = name.toCharArray();
  422.     }
  423.  
  424.     /**
  425.      * Gets and returns this Thread's name.
  426.      * @see Thread#setName
  427.      */
  428.     public final String getName() {
  429.     return String.valueOf(name);
  430.     }
  431.  
  432.     /**
  433.      * Gets and returns this Thread group.
  434.      */
  435.     public final ThreadGroup getThreadGroup() {
  436.     return group;
  437.     }
  438.  
  439.  
  440.     /**
  441.      * Returns the current number of active Threads in this Thread group.
  442.      */
  443.     public static int activeCount() {
  444.     return currentThread().getThreadGroup().activeCount();
  445.     }
  446.  
  447.     /**
  448.      * Copies, into the specified array, references to every active Thread in this 
  449.      * Thread's group.
  450.      * @return the number of Threads put into the array.
  451.      */
  452.     public static int enumerate(Thread tarray[]) {
  453.     return currentThread().getThreadGroup().enumerate(tarray);
  454.     }
  455.  
  456.     /**
  457.      * Returns the number of stack frames in this Thread. The Thread
  458.      * must be suspended when this method is called.
  459.      * @exception    IllegalThreadStateException If the Thread is not suspended.
  460.      */
  461.     public native int countStackFrames();
  462.  
  463.     /**
  464.      * Waits for this Thread to die.  A timeout in milliseconds can
  465.      * be specified.  A timeout of 0 milliseconds means to wait
  466.      * forever.
  467.      * @param millis    the time to wait in milliseconds
  468.      */
  469.     public final synchronized void join(long millis) throws InterruptedException {
  470.     long base = System.currentTimeMillis();
  471.     long now = 0;
  472.  
  473.     if (millis == 0) {
  474.         while (isAlive()) {
  475.         wait(0);
  476.         }
  477.     } else {
  478.         while (isAlive()) {
  479.         long delay = millis - now;
  480.         if (delay <= 0) {
  481.             break;
  482.         }
  483.         wait(delay);
  484.         now = System.currentTimeMillis() - base;
  485.         }
  486.     }
  487.     }
  488.  
  489.     /**
  490.      * Waits for the Thread to die, with more precise time.
  491.      */
  492.     public final synchronized void join(long millis, int nanos) throws InterruptedException {
  493.     if (nanos >= 500000 || millis == 0)
  494.         millis++;
  495.     join(millis);
  496.     }
  497.  
  498.  
  499.     /**
  500.      * Waits forever for this Thread to die.
  501.      */
  502.     public final void join() throws InterruptedException {
  503.     join(0);
  504.     }
  505.  
  506.     /**
  507.      * A debugging procedure to print a stack trace for the
  508.      * current Thread.
  509.      * @see Exception#printStackTrace
  510.      */
  511.     public static void dumpStack() {
  512.     new Exception("Stack trace").printStackTrace();
  513.     }
  514.  
  515.     /**
  516.      * Marks this Thread as a daemon Thread or a user Thread.
  517.      * When there are only daemon Threads left running in the
  518.      * system, Java exits.
  519.      * @param on    determines whether the Thread will be a daemon Thread
  520.      * @exception IllegalThreadStateException If the Thread is active.
  521.      * @see Thread#isDaemon
  522.      */
  523.     public final void setDaemon(boolean on) {
  524.     checkAccess();
  525.     if (isAlive()) {
  526.         throw new IllegalThreadStateException();
  527.     }
  528.     daemon = on;
  529.     }
  530.  
  531.     /**
  532.      * Returns the daemon flag of the Thread.
  533.      * @see Thread#setDaemon
  534.      */
  535.     public final boolean isDaemon() {
  536.     return daemon;
  537.     }
  538.  
  539.     /**
  540.      * Checks whether the current Thread is allowed to modify this Thread.
  541.      * @exception SecurityException If the current Thread is not allowed 
  542.      * to access this Thread group.
  543.      */
  544.     public void checkAccess() {
  545.     SecurityManager security = System.getSecurityManager();
  546.     if (security != null) {
  547.         security.checkAccess(this);
  548.     }
  549.     }
  550.  
  551.     /**
  552.      * Returns a String representation of the Thread.
  553.      */
  554.     public String toString() {
  555.     return "Thread[" + getName() + "," + getPriority() + "," + 
  556.             getThreadGroup().getName() + "]";
  557.     }
  558.  
  559.     /* Some private helper methods */
  560.     private native void setPriority0(int newPriority);
  561.     private native void stop0(Object o);
  562.     private native void suspend0();
  563.     private native void resume0();
  564. }
  565.