/* * * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package java.lang; /** * A <i>thread</i> is a thread of execution in a program. The Java * Virtual Machine allows an application to have multiple threads of * execution running concurrently. * <p> * Every thread has a priority. Threads with higher priority are * executed in preference to threads with lower priority. * <p> * There are two ways to create a new thread of execution. One is to * declare a class to be a subclass of <code>Thread</code>. This * subclass should override the <code>run</code> method of class * <code>Thread</code>. An instance of the subclass can then be * allocated and started. For example, a thread that computes primes * larger than a stated value could be written as follows: * <p><hr><blockquote><pre> * class PrimeThread extends Thread { * long minPrime; * PrimeThread(long minPrime) { * this.minPrime = minPrime; * } * * public void run() { * // compute primes larger than minPrime *  . . . * } * } * </pre></blockquote><hr> * <p> * The following code would then create a thread and start it running: * <p><blockquote><pre> * PrimeThread p = new PrimeThread(143); * p.start(); * </pre></blockquote> * <p> * The other way to create a thread is to declare a class that * implements the <code>Runnable</code> interface. That class then * implements the <code>run</code> method. An instance of the class can * then be allocated, passed as an argument when creating * <code>Thread</code>, and started. The same example in this other * style looks like the following: * <p><hr><blockquote><pre> * class PrimeRun implements Runnable { * long minPrime; * PrimeRun(long minPrime) { * this.minPrime = minPrime; * } * * public void run() { * // compute primes larger than minPrime *  . . . * } * } * </pre></blockquote><hr> * <p> * The following code would then create a thread and start it running: * <p><blockquote><pre> * PrimeRun p = new PrimeRun(143); * new Thread(p).start(); * </pre></blockquote> * <p> * * * @version 1.105, 12/04/99 (CLDC 1.0, Spring 2000) * @see java.lang.Runnable * @see java.lang.Runtime#exit(int) * @see java.lang.Thread#run() * @since JDK1.0 */ public class Thread implements Runnable { /* Reminder: CLDC threads don't have a name. This saves space. */ /* Thread priority */ private int priority = NORM_PRIORITY; /* What will be run. */ private Runnable target; /* VM local variables */ private Object vm_thread; private int is_terminated; private int is_stillborn; /** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10; /** * Returns a reference to the currently executing thread object. * * @return the currently executing thread. */ public static native Thread currentThread(); /** * Causes the currently executing thread object to temporarily pause * and allow other threads to execute. */ public static native void yield(); /** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds. The thread * does not lose ownership of any monitors. * * @param millis the length of time to sleep in milliseconds. * @exception InterruptedException if another thread has interrupted * the current thread. The <i>interrupted status</i> of the * current thread is cleared when this exception is thrown. * @see java.lang.Object#notify() */ public static native void sleep(long millis) throws InterruptedException; /** * Allocates a new <code>Thread</code> object. * <p> * Threads created this way must have overridden their * <code>run()</code> method to actually do anything. * * @see java.lang.Runnable */ public Thread() { /* The VM initializes the thread "under the hood" */ // this(null); } /** * Allocates a new <code>Thread</code> object with a * specific target object whose <code>run</code> method * is called. * * @param target the object whose <code>run</code> method is called. */ public Thread(Runnable target) { Thread parent = currentThread(); this.priority = parent.getPriority(); this.target = target; setPriority(priority); } /** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * * @exception IllegalThreadStateException if the thread was already * started. * @see java.lang.Thread#run() */ public synchronized void start() { start(this); } private static synchronized void start(Thread thread) { thread.start0(); } private native void start0(); /** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see java.lang.Thread#start() * @see java.lang.Runnable#run() */ public void run() { if (target != null) { target.run(); } } /** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @return <code>true</code> if this thread is alive; * <code>false</code> otherwise. */ public final native boolean isAlive(); /** * Changes the priority of this thread. * * @param newPriority priority to set this thread to * @exception IllegalArgumentException If the priority is not in the * range <code>MIN_PRIORITY</code> to * <code>MAX_PRIORITY</code>. * @see #getPriority * @see java.lang.Thread#getPriority() * @see java.lang.Thread#MAX_PRIORITY * @see java.lang.Thread#MIN_PRIORITY */ public final void setPriority(int newPriority) { if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } setPriority0(priority, newPriority); priority = newPriority; } /** * Returns this thread's priority. * * @return this thread's priority. * @see #setPriority * @see java.lang.Thread#setPriority(int) */ public final int getPriority() { return priority; } /** * Returns the current number of active threads in the VM. * * @return the current number of active threads. */ public static native int activeCount(); /** * Waits for this thread to die. * * @exception InterruptedException if another thread has interrupted * the current thread. The <i>interrupted status</i> of the * current thread is cleared when this exception is thrown. */ public final synchronized void join() throws InterruptedException { while (isAlive()) { wait(1000); } } /** * Returns a string representation of this thread, including a unique number * that identifies the thread and the thread's priority. * * @return a string representation of this thread. */ public String toString() { return "Thread[@" + hashCode() + "," + getPriority() + "]"; } /* Some private helper methods */ private native void setPriority0(int oldPriority, int newPriority); private synchronized native void internalExit(); }