package java.lang; /** * A thread of execution (or task). Now handles priorities, daemon threads * and interruptions. */ public class Thread implements Runnable { /** * The minimum priority that a thread can have. The value is 1. */ public final static int MIN_PRIORITY = 1; /** * The priority that is assigned to the primordial thread. The value is 5. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. The value is 10. */ public final static int MAX_PRIORITY = 10; // Note 1: This class cannot have a static initializer. // Note 2: The following fields are used by the VM. // Their sizes and location can only be changed // if classes.h is changed accordingly. Needless // to say, they are read-only. private Thread _TVM_nextThread; private Object _TVM_waitingOn; private int _TVM_sync; private int _TVM_sleepUntil; private Object _TVM_stackFrameArray; private Object _TVM_stackArray; private byte _TVM_stackFrameArraySize; private byte _TVM_monitorCount; private byte _TVM_threadId; private byte _TVM_state; private byte _TVM_priority; private byte _TVM_interrupted; private byte _TVM_daemon; // Extra instance state follows: private String name; public final boolean isAlive() { return _TVM_state > 1; } private void init(String name, Runnable target) { Thread t = currentThread(); if (t == null) setPriority(NORM_PRIORITY); else { setPriority(t.getPriority()); setDaemon(t.isDaemon()); } this.name = name; // This is a little naughty. We should not really use the internal fields // of the task block. However the waitingOn field can not and is not used // until after the thread has been started, so it is reasonably safe to use // it to hold the target since this will only be used when the thread // is first run. Also this saves haveing an extra ref. in such a basic // type. this._TVM_waitingOn = target; } public Thread() { init("", null); } public Thread (String name) { init(name, null); } public Thread(Runnable target) { init("", target); } public Thread(String name, Runnable target) { init(name, target); } public void run() { // If the thead was created with a runnable it will be stored in waitingOn // Note it is not safe to use this field again after this point. if (_TVM_waitingOn != null) ((Runnable)_TVM_waitingOn).run(); } public final native void start(); public static native void yield(); public static native void sleep (long aMilliseconds) throws InterruptedException; public static native Thread currentThread(); public final native int getPriority(); /** * Returns the string name of this thread. * @return The name of this thread. */ public String getName() { return name; } /** * Sets the string name associated with this thread. * @param name The new name of the thread. */ public void setName(String name) { this.name = name; } /** * Set the priority of this thread. Higher number have higher priority. * The scheduler will always run the highest priority thread in preference * to any others. If more than one thread of that priority exists the * scheduler will time-slice them. In order for lower priority threas * to run a higher priority thread must cease to be runnable. i.e. it * must exit, sleep or wait on a monitor. It is not sufficient to just * yield. * <P> * Threads inherit the priority of their parent. The primordial thread * has priority NORM_PRIORITY. * * @param priority must be between MIN_PRIORITY and MAX_PRIORITY. */ public final native void setPriority(int priority); /** * Set the interrupted flag. If we are asleep we will wake up * and an InterruptedException will be thrown. */ public native void interrupt(); public static native boolean interrupted(); public final native boolean isInterrupted(); /** * Set the daemon flag. If a thread is a daemon thread its existence will * not prevent a JVM from exiting. */ public final native boolean isDaemon(); public final native void setDaemon(boolean on); /** * Join not yet implemented */ public final native void join() throws InterruptedException; public final native void join(long timeout) throws InterruptedException; }