diff options
author | Aaron M. Renn <arenn@urbanophile.com> | 1998-12-25 05:02:03 +0000 |
---|---|---|
committer | Aaron M. Renn <arenn@urbanophile.com> | 1998-12-25 05:02:03 +0000 |
commit | 53ecdf08c68638d38ca7b88d57009b1ff8bfef5c (patch) | |
tree | b523793d300e3f4070c7be642b1c2a6ba30dcbdd /vm | |
parent | 6e9c6f61e26dfeafa81f3117e6c7cab1a77cc5fb (diff) | |
download | classpath-53ecdf08c68638d38ca7b88d57009b1ff8bfef5c.tar.gz |
Make the run() method actually run the code it is supposed to!
Diffstat (limited to 'vm')
-rw-r--r-- | vm/reference/java/lang/Thread.java | 1032 |
1 files changed, 517 insertions, 515 deletions
diff --git a/vm/reference/java/lang/Thread.java b/vm/reference/java/lang/Thread.java index bf7bd4aee..a39b34ee9 100644 --- a/vm/reference/java/lang/Thread.java +++ b/vm/reference/java/lang/Thread.java @@ -1,521 +1,523 @@ -/*
- * java.lang.Thread: part of the Java Class Libraries project.
- * Copyright (C) 1998 John Keiser
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-package java.lang;
-
-/**
- ** Thread represents a single thread of execution in the VM.
- ** When an application VM starts up, it creates a new Thread
- ** which calls the main() method of a particular class. There
- ** may be other Threads running, such as the garbage collection
- ** thread.<P>
- **
- ** Threads have names to identify them. These names are not
- ** necessarily unique.<P>
- **
- ** Every Thread has a priority, as well, which tells the VM
- ** which Threads get more running time.<P>
- **
- ** There are two methods of creating a Thread: you may
- ** subclass Thread and implement the <CODE>run()</CODE> method, at which
- ** point you may start the Thread by calling its <CODE>start()</CODE>
- ** method, or you may implement <CODE>Runnable</CODE> in the class you
- ** want to use and then call new <CODE>Thread(your_obj).start()</CODE>.
- **
- ** @specnote it is unclear at what point a Thread should be added to a
- ** ThreadGroup, and at what point it should be removed.
- ** Should it be inserted when it starts, or when it is
- ** created? Should it be removed when it is suspended or
- ** interrupted? The only thing that is clear is that the
- ** Thread should be removed when it is stopped.
- ** @author John Keiser
- ** @version 1.1.0, Aug 6 1998
- ** @since JDK1.0
- **/
-
-public class Thread {
- ThreadGroup group;
- Runnable toRun;
- String name;
- boolean daemon;
- int priority;
-
- /** The maximum priority for a Thread.
- ** @XXX find out the value for this.
- **/
- public static final int MAX_PRIORITY = 100;
-
- /** The priority a Thread gets by default.
- ** @XXX find out the value for this.
- **/
- public static final int NORM_PRIORITY = 50;
-
- /** The minimum priority for a Thread.
- ** @XXX find out the value for this.
- **/
- public static final int MIN_PRIORITY = 0;
-
- static int numThreadsCreated = 0;
-
-
- /** Allocate a new Thread object, with the same ThreadGroup
- ** as the calling thread, with an automatic name, and using
- ** Thread's <CODE>run()</CODE> method to execute.<P>
- **
- ** The new Thread will inherit its creator's priority and
- ** will be marked as a daemon if its creator is a daemon.<P>
- **
- ** This method is identical to calling
- ** <CODE>Thread(null,null,<I>fake name</I>)</CODE>, where the
- ** fake name in this case is automatically generated with the
- ** name "Thread-" + <I>arbitrary integer</I>.
- **/
- public Thread() {
- this(null,null,null);
- }
-
- /** Allocate a new Thread object, with the same ThreadGroup
- ** as the calling thread, with an automatic name, and using
- ** the specified Runnable object's <CODE>run()</CODE> method
- ** to execute. If the Runnable object is null, Thread's
- ** <CODE>run()</CODE> will be called instead.<P>
- **
- ** The new Thread will inherit its creator's priority and
- ** will be marked as a daemon if its creator is a daemon.<P>
- **
- ** This method is identical to calling
- ** <CODE>Thread(null,target,<I>fake name</I>)</CODE>, where the
- ** fake name in this case is automatically generated with the
- ** name "Thread-" + <I>arbitrary integer</I>.
- **
- ** @param toRun the Runnable object to execute.
- **/
- public Thread(Runnable toRun) {
- this(null,toRun);
- }
-
- /** Allocate a new Thread object, with the specified ThreadGroup,
- ** with an automatic name, and using the specified Runnable
- ** object's <CODE>run()</CODE> method to execute. If the
- ** Runnable object is null, Thread's <CPDE>run()</CODE> will be
- ** called instead. If the ThreadGroup object is null, the Thread
- ** will get the same ThreadGroup as the creating Thread.<P>
- **
- ** The new Thread will inherit its creator's priority and
- ** will be marked as a daemon if its creator is a daemon.<P>
- **
- ** This method is identical to calling
- ** <CODE>Thread(null,target,<I>fake name</I>)</CODE>, where the
- ** fake name in this case is automatically generated with the
- ** name "Thread-" + <I>arbitrary integer</I>.
- **
- ** @param group the group to put the Thread into.
- ** @param target the Runnable object to execute.
- **
- ** @exception SecurityException if this thread cannot access the
- ** specified ThreadGroup.
- **/
- public Thread(ThreadGroup group, Runnable toRun) {
- this(group,toRun,"Thread-" + (++numThreadsCreated));
- }
-
- /** Allocate a new Thread object, with the same ThreadGroup
- ** as the calling thread, with the specified name, and using
- ** Thread's <CODE>run()</CODE> method to execute.<P>
- **
- ** The new Thread will inherit its creator's priority and
- ** will be marked as a daemon if its creator is a daemon.<P>
- **
- ** This method is identical to calling
- ** <CODE>Thread(null,null,name)</CODE>.
- **
- ** @param name the name for the Thread.
- **/
- public Thread(String name) {
- this(null,null,name);
- }
-
- /** Allocate a new Thread object, with the same ThreadGroup
- ** as the calling thread, with the specified name, and using
- ** the specified Runnable object's <CODE>run()</CODE> method
- ** to execute. If the Runnable object is null, Thread's
- ** <CPDE>run()</CODE> will be called instead.<P>
- **
- ** The new Thread will inherit its creator's priority and
- ** will be marked as a daemon if its creator is a daemon.<P>
- **
- ** This method is identical to calling
- ** <CODE>Thread(null,target,name)</CODE>.
- **
- ** @param toRun the Runnable object to execute.
- ** @param name the name for the Thread.
- **/
- public Thread(Runnable toRun, String name) {
- this(null,toRun,name);
- }
-
- private Thread(ThreadGroup group, String name) {
- this(group,null,name);
- }
-
- /** Allocate a new Thread object, with the specified ThreadGroup,
- ** with the specified name, and using the specified Runnable
- ** object's <CODE>run()</CODE> method to execute. If the
- ** Runnable object is null, Thread's <CPDE>run()</CODE> will be
- ** called instead. If the ThreadGroup object is null, the Thread
- ** will get the same ThreadGroup as the creating Thread.<P>
- **
- ** The new Thread will inherit its creator's priority and
- ** will be marked as a daemon if its creator is a daemon.
- **
- ** @param group the group to put the Thread into.
- ** @param target the Runnable object to execute.
- ** @param name the name for the Thread.
- **
- ** @exception SecurityException if this thread cannot access the
- ** specified ThreadGroup.
- **/
- public Thread(ThreadGroup group, Runnable toRun, String name) {
- if(group != null) {
- this.group = group;
- group.checkAccess();
- } else {
- this.group = currentThread().getThreadGroup();
- }
- this.toRun = toRun;
- this.name = name;
- priority = currentThread().getPriority();
- daemon = currentThread().isDaemon();
- nativeInit();
-
- this.group.addThread(this);
- }
-
- /** Get the currently executing Thread.
- ** @return the currently executing Thread.
- **/
- public static native Thread currentThread();
-
- /** Suspend the current Thread's execution for the specified
- ** amount of time. The Thread will not lose any locks it has
- ** during this time.
- **
- ** @param ms the number of milliseconds to sleep.
- ** @exception InterruptedException if the Thread is interrupted
- ** by another Thread.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public static void sleep(long ms) throws InterruptedException {
- sleep(ms,0);
- }
-
- /** Suspend the current Thread's execution for the specified
- ** amount of time. The Thread will not lose any locks it has
- ** during this time.
- **
- ** @param ms the number of milliseconds to sleep.
- ** @param ns the number of extra nanoseconds to sleep (0-999999).
- ** @exception InterruptedException if the Thread is interrupted
- ** by another Thread.
- **/
- public static native void sleep(long ms, int ns) throws InterruptedException;
-
- /** Start this Thread, calling the run() method of the Runnable
- ** this Thread was created with or else the run() method of the
- ** Thread itself.
- **/
+/* + * java.lang.Thread: part of the Java Class Libraries project. + * Copyright (C) 1998 John Keiser + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +package java.lang; + +/** + ** Thread represents a single thread of execution in the VM. + ** When an application VM starts up, it creates a new Thread + ** which calls the main() method of a particular class. There + ** may be other Threads running, such as the garbage collection + ** thread.<P> + ** + ** Threads have names to identify them. These names are not + ** necessarily unique.<P> + ** + ** Every Thread has a priority, as well, which tells the VM + ** which Threads get more running time.<P> + ** + ** There are two methods of creating a Thread: you may + ** subclass Thread and implement the <CODE>run()</CODE> method, at which + ** point you may start the Thread by calling its <CODE>start()</CODE> + ** method, or you may implement <CODE>Runnable</CODE> in the class you + ** want to use and then call new <CODE>Thread(your_obj).start()</CODE>. + ** + ** @specnote it is unclear at what point a Thread should be added to a + ** ThreadGroup, and at what point it should be removed. + ** Should it be inserted when it starts, or when it is + ** created? Should it be removed when it is suspended or + ** interrupted? The only thing that is clear is that the + ** Thread should be removed when it is stopped. + ** @author John Keiser + ** @version 1.1.0, Aug 6 1998 + ** @since JDK1.0 + **/ + +public class Thread { + ThreadGroup group; + Runnable toRun; + String name; + boolean daemon; + int priority; + + /** The maximum priority for a Thread. + ** @XXX find out the value for this. + **/ + public static final int MAX_PRIORITY = 100; + + /** The priority a Thread gets by default. + ** @XXX find out the value for this. + **/ + public static final int NORM_PRIORITY = 50; + + /** The minimum priority for a Thread. + ** @XXX find out the value for this. + **/ + public static final int MIN_PRIORITY = 0; + + static int numThreadsCreated = 0; + + + /** Allocate a new Thread object, with the same ThreadGroup + ** as the calling thread, with an automatic name, and using + ** Thread's <CODE>run()</CODE> method to execute.<P> + ** + ** The new Thread will inherit its creator's priority and + ** will be marked as a daemon if its creator is a daemon.<P> + ** + ** This method is identical to calling + ** <CODE>Thread(null,null,<I>fake name</I>)</CODE>, where the + ** fake name in this case is automatically generated with the + ** name "Thread-" + <I>arbitrary integer</I>. + **/ + public Thread() { + this(null,null,null); + } + + /** Allocate a new Thread object, with the same ThreadGroup + ** as the calling thread, with an automatic name, and using + ** the specified Runnable object's <CODE>run()</CODE> method + ** to execute. If the Runnable object is null, Thread's + ** <CODE>run()</CODE> will be called instead.<P> + ** + ** The new Thread will inherit its creator's priority and + ** will be marked as a daemon if its creator is a daemon.<P> + ** + ** This method is identical to calling + ** <CODE>Thread(null,target,<I>fake name</I>)</CODE>, where the + ** fake name in this case is automatically generated with the + ** name "Thread-" + <I>arbitrary integer</I>. + ** + ** @param toRun the Runnable object to execute. + **/ + public Thread(Runnable toRun) { + this(null,toRun); + } + + /** Allocate a new Thread object, with the specified ThreadGroup, + ** with an automatic name, and using the specified Runnable + ** object's <CODE>run()</CODE> method to execute. If the + ** Runnable object is null, Thread's <CPDE>run()</CODE> will be + ** called instead. If the ThreadGroup object is null, the Thread + ** will get the same ThreadGroup as the creating Thread.<P> + ** + ** The new Thread will inherit its creator's priority and + ** will be marked as a daemon if its creator is a daemon.<P> + ** + ** This method is identical to calling + ** <CODE>Thread(null,target,<I>fake name</I>)</CODE>, where the + ** fake name in this case is automatically generated with the + ** name "Thread-" + <I>arbitrary integer</I>. + ** + ** @param group the group to put the Thread into. + ** @param target the Runnable object to execute. + ** + ** @exception SecurityException if this thread cannot access the + ** specified ThreadGroup. + **/ + public Thread(ThreadGroup group, Runnable toRun) { + this(group,toRun,"Thread-" + (++numThreadsCreated)); + } + + /** Allocate a new Thread object, with the same ThreadGroup + ** as the calling thread, with the specified name, and using + ** Thread's <CODE>run()</CODE> method to execute.<P> + ** + ** The new Thread will inherit its creator's priority and + ** will be marked as a daemon if its creator is a daemon.<P> + ** + ** This method is identical to calling + ** <CODE>Thread(null,null,name)</CODE>. + ** + ** @param name the name for the Thread. + **/ + public Thread(String name) { + this(null,null,name); + } + + /** Allocate a new Thread object, with the same ThreadGroup + ** as the calling thread, with the specified name, and using + ** the specified Runnable object's <CODE>run()</CODE> method + ** to execute. If the Runnable object is null, Thread's + ** <CPDE>run()</CODE> will be called instead.<P> + ** + ** The new Thread will inherit its creator's priority and + ** will be marked as a daemon if its creator is a daemon.<P> + ** + ** This method is identical to calling + ** <CODE>Thread(null,target,name)</CODE>. + ** + ** @param toRun the Runnable object to execute. + ** @param name the name for the Thread. + **/ + public Thread(Runnable toRun, String name) { + this(null,toRun,name); + } + + private Thread(ThreadGroup group, String name) { + this(group,null,name); + } + + /** Allocate a new Thread object, with the specified ThreadGroup, + ** with the specified name, and using the specified Runnable + ** object's <CODE>run()</CODE> method to execute. If the + ** Runnable object is null, Thread's <CPDE>run()</CODE> will be + ** called instead. If the ThreadGroup object is null, the Thread + ** will get the same ThreadGroup as the creating Thread.<P> + ** + ** The new Thread will inherit its creator's priority and + ** will be marked as a daemon if its creator is a daemon. + ** + ** @param group the group to put the Thread into. + ** @param target the Runnable object to execute. + ** @param name the name for the Thread. + ** + ** @exception SecurityException if this thread cannot access the + ** specified ThreadGroup. + **/ + public Thread(ThreadGroup group, Runnable toRun, String name) { + if(group != null) { + this.group = group; + group.checkAccess(); + } else { + this.group = currentThread().getThreadGroup(); + } + this.toRun = toRun; + this.name = name; + priority = currentThread().getPriority(); + daemon = currentThread().isDaemon(); + nativeInit(); + + this.group.addThread(this); + } + + /** Get the currently executing Thread. + ** @return the currently executing Thread. + **/ + public static native Thread currentThread(); + + /** Suspend the current Thread's execution for the specified + ** amount of time. The Thread will not lose any locks it has + ** during this time. + ** + ** @param ms the number of milliseconds to sleep. + ** @exception InterruptedException if the Thread is interrupted + ** by another Thread. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public static void sleep(long ms) throws InterruptedException { + sleep(ms,0); + } + + /** Suspend the current Thread's execution for the specified + ** amount of time. The Thread will not lose any locks it has + ** during this time. + ** + ** @param ms the number of milliseconds to sleep. + ** @param ns the number of extra nanoseconds to sleep (0-999999). + ** @exception InterruptedException if the Thread is interrupted + ** by another Thread. + **/ + public static native void sleep(long ms, int ns) throws InterruptedException; + + /** Start this Thread, calling the run() method of the Runnable + ** this Thread was created with or else the run() method of the + ** Thread itself. + **/ public synchronized native void start(); -
- /** The method of Thread that will be run if there is no Runnable
- ** object associated with the Thread.<P>
- **
- ** Thread's implementation does nothing at all.
- **/
- public void run() {
- }
-
- /** Cause this Thread to stop abnormally and throw a ThreadDeath
- ** exception.<P>
- **
- ** If you stop a Thread that has not yet started, it will stop
- ** immediately when it is actually started.<P>
- **
- ** @exception SecurityException if you cannot modify this Thread.
- ** @XXX it doesn't yet implement that second requirement.
- **/
- public final void stop() {
- stop(new ThreadDeath());
- }
-
- /** Cause this Thread to stop abnormally and throw the specified
- ** exception.<P>
- **
- ** If you stop a Thread that has not yet started, it will stop
- ** immediately when it is actually started.<P>
- **
- ** @param t the Throwable to throw when the Thread dies.
- ** @exception SecurityException if you cannot modify this Thread.
- ** @XXX it doesn't yet implement that second requirement.
- **/
- public final synchronized void stop(Throwable t) {
- checkAccess();
- group.removeThread(this);
- nativeStop(t);
- }
-
+ + /** The method of Thread that will be run if there is no Runnable + ** object associated with the Thread.<P> + ** + ** Thread's implementation does nothing at all. + **/ + public void run() { + if (toRun != null) + toRun.run(); + } + + /** Cause this Thread to stop abnormally and throw a ThreadDeath + ** exception.<P> + ** + ** If you stop a Thread that has not yet started, it will stop + ** immediately when it is actually started.<P> + ** + ** @exception SecurityException if you cannot modify this Thread. + ** @XXX it doesn't yet implement that second requirement. + **/ + public final void stop() { + stop(new ThreadDeath()); + } + + /** Cause this Thread to stop abnormally and throw the specified + ** exception.<P> + ** + ** If you stop a Thread that has not yet started, it will stop + ** immediately when it is actually started.<P> + ** + ** @param t the Throwable to throw when the Thread dies. + ** @exception SecurityException if you cannot modify this Thread. + ** @XXX it doesn't yet implement that second requirement. + **/ + public final synchronized void stop(Throwable t) { + checkAccess(); + group.removeThread(this); + nativeStop(t); + } + /** ** Yield to another thread **/ public synchronized native void yield(); - /** Interrupt this Thread.
- ** It is not clear whether locks this Thread has should be released.
- ** This operation will only take place if the Thread is suspended
- ** or is sleeping.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public synchronized void interrupt() {
- checkAccess();
- nativeInterrupt();
- }
-
- /** Destroy this thread. Don't even bother to clean up locks.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public synchronized void destroy() {
- checkAccess();
- group.removeThread(this);
- nativeDestroy();
- }
-
- /** Suspend this Thread. It will not come back, ever, unless
- ** it is resumed. It is not clear whether locks should be
- ** released until resumption, but it is likely.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public final synchronized void suspend() {
- checkAccess();
- nativeSuspend();
- }
-
- /** Resume this Thread. If the thread is not suspended, this
- ** method does nothing.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public final synchronized void resume() {
- checkAccess();
- nativeResume();
- }
-
- /** Wait forever for the Thread in question to die.
- ** @exception InterruptedException if this Thread is interrupted
- ** while waiting.
- **/
- public final void join() throws InterruptedException {
- join(0,0);
- }
-
- /** Wait the specified amount of time for the Thread in question to
- ** die.
- ** @param ms the number of milliseconds to wait, or 0 for forever.
- ** @exception InterruptedException if this Thread is interrupted
- ** while waiting.
- **/
- public final void join(long ms) throws InterruptedException {
- join(ms,0);
- }
-
- /** Wait the specified amount of time for the Thread in question to
- ** die.
- ** @param ms the number of milliseconds to wait, or 0 for forever.
- ** @param ns the number of nanoseconds (0-999999) to wait, or 0 for
- ** forever.
- ** @exception InterruptedException if this Thread is interrupted
- ** while waiting.
- ** @XXX a ThreadListener would be nice. Then perhaps this could be
- ** made efficient.
- **/
- public final void join(long ms, int ns) throws InterruptedException {
- if(ms == 0 && ns == 0) {
- while(!isAlive())
- currentThread().sleep(1);
- } else {
- for(long i=0;i<ms;i++) {
- if(isAlive())
- return;
- currentThread().sleep(1);
- }
- currentThread().sleep(0,ns);
- }
- }
-
- /** Print a stack trace of the current thread to stderr using
- ** the same format as Throwable's printStackTrace() method.
- **/
- public static void dumpStack() {
- new Throwable().printStackTrace();
- }
-
-
- /** Set this Thread's priority.
- ** @param priority the new priority for this Thread.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public final void setPriority(int priority) {
- checkAccess();
- if(priority < MIN_PRIORITY
- || priority > MAX_PRIORITY
- || priority > group.getMaxPriority())
- throw new IllegalArgumentException("Invalid thread priority value " + priority + ".");
- this.priority = priority;
- nativeSetPriority(priority);
- }
-
- /** Get this Thread's priority.
- ** @return the Thread's priority.
- **/
- public final int getPriority() {
- return priority;
- }
-
- /** Set this Thread's name.
- ** @param name the new name for this Thread.
- ** @exception SecurityException if you cannot modify this Thread.
- **/
- public final void setName(String name) {
- checkAccess();
- this.name = name;
- }
-
- /** Get this Thread's name.
- ** @return this Thread's name.
- **/
- public final String getName() {
- return name;
- }
-
- /** Get the ThreadGroup this Thread belongs to.
- ** @return this Thread's ThreadGroup.
- **/
- public final ThreadGroup getThreadGroup() {
- return group;
- }
-
- /** Set the daemon status of this Thread. If this is a
- ** daemon Thread, then the VM may exit even if it is still
- ** running. This may only be called when the Thread is not
- ** running.
- **
- ** @specnote It is possible that this should only be called
- ** if the Thread has not been started. This
- ** interpretation was easier to implement, though,
- ** so it's the one I chose :)
- ** @param daemon whether this should be a daemon thread or not.
- ** @exception SecurityException if you cannot modify this Thread.
- ** @exception IllegalThreadStateException if the Thread is active.
- **/
- public final void setDaemon(boolean daemon) {
- this.daemon = daemon;
- }
-
- /** Tell whether this is a daemon Thread or not.
- ** @return whether this is a daemon Thread or not.
- **/
- public final boolean isDaemon() {
- return daemon;
- }
-
-
- /** Get the number of active threads in the current Thread's
- ** ThreadGroup. This implementation calls
- ** <CODE>currentThread().getThreadGroup().activeCount()</CODE>.
- ** @return the number of active threads in the current Thread's
- ** ThreadGroup.
- **/
- public static int activeCount() {
- return currentThread().group.activeCount();
- }
-
- /** Copy every active thread in the current Thread's ThreadGroup
- ** into the array. This implementation calls
- ** <CODE>getThreadGroup().enumerate(array)</CODE>
- ** @param array the array to place the Threads into.
- ** @return the number of Threads placed into the array.
- **/
- public static int enumerate(Thread[] array) {
- return currentThread().group.enumerate(array);
- }
-
- /** Count the number of stack frames in this Thread. The Thread
- ** in question must be suspended when this occurs.
- **
- ** @return the number of stack frames in this Thread.
- ** @exception IllegalThreadStateException if this Thread is
- ** not suspended.
- **/
- public native int countStackFrames();
-
-
- /** Determine whether the current Thread has been interrupted.
- ** @return whether the current Thread has been interrupted.
- **/
- public static boolean interrupted() {
- return currentThread().isInterrupted();
- }
-
- /** Determine whether this Thread has been interrupted.
- ** @return whether this Thread has been interrupted.
- **/
- public native boolean isInterrupted();
-
- /** Determine whether this Thread is alive.
- ** @return whether this Thread is alive.
- **/
- public final native boolean isAlive();
-
-
- /** Check whether the current Thread is allowed to
- ** modify this Thread.
- ** @exception SecurityException if the current Thread cannot
- ** modify this Thread.
- **/
- public void checkAccess() {
- SecurityManager sm = System.getSecurityManager();
- if(sm != null) {
- sm.checkAccess(this);
- }
- }
-
- /** Return a human-readable String representing this Thread.
- ** @return a human-readable String representing this Thread.
- ** @XXX determine the exact format of this String.
- **/
- public String toString() {
- return "";
- }
-
- final native void nativeInit();
- final native void nativeStop(Throwable t);
- final native void nativeInterrupt();
- final native void nativeDestroy();
- final native void nativeSuspend();
- final native void nativeResume();
- final native void nativeSetPriority(int newPriority);
-}
+ /** Interrupt this Thread. + ** It is not clear whether locks this Thread has should be released. + ** This operation will only take place if the Thread is suspended + ** or is sleeping. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public synchronized void interrupt() { + checkAccess(); + nativeInterrupt(); + } + + /** Destroy this thread. Don't even bother to clean up locks. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public synchronized void destroy() { + checkAccess(); + group.removeThread(this); + nativeDestroy(); + } + + /** Suspend this Thread. It will not come back, ever, unless + ** it is resumed. It is not clear whether locks should be + ** released until resumption, but it is likely. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public final synchronized void suspend() { + checkAccess(); + nativeSuspend(); + } + + /** Resume this Thread. If the thread is not suspended, this + ** method does nothing. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public final synchronized void resume() { + checkAccess(); + nativeResume(); + } + + /** Wait forever for the Thread in question to die. + ** @exception InterruptedException if this Thread is interrupted + ** while waiting. + **/ + public final void join() throws InterruptedException { + join(0,0); + } + + /** Wait the specified amount of time for the Thread in question to + ** die. + ** @param ms the number of milliseconds to wait, or 0 for forever. + ** @exception InterruptedException if this Thread is interrupted + ** while waiting. + **/ + public final void join(long ms) throws InterruptedException { + join(ms,0); + } + + /** Wait the specified amount of time for the Thread in question to + ** die. + ** @param ms the number of milliseconds to wait, or 0 for forever. + ** @param ns the number of nanoseconds (0-999999) to wait, or 0 for + ** forever. + ** @exception InterruptedException if this Thread is interrupted + ** while waiting. + ** @XXX a ThreadListener would be nice. Then perhaps this could be + ** made efficient. + **/ + public final void join(long ms, int ns) throws InterruptedException { + if(ms == 0 && ns == 0) { + while(!isAlive()) + currentThread().sleep(1); + } else { + for(long i=0;i<ms;i++) { + if(isAlive()) + return; + currentThread().sleep(1); + } + currentThread().sleep(0,ns); + } + } + + /** Print a stack trace of the current thread to stderr using + ** the same format as Throwable's printStackTrace() method. + **/ + public static void dumpStack() { + new Throwable().printStackTrace(); + } + + + /** Set this Thread's priority. + ** @param priority the new priority for this Thread. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public final void setPriority(int priority) { + checkAccess(); + if(priority < MIN_PRIORITY + || priority > MAX_PRIORITY + || priority > group.getMaxPriority()) + throw new IllegalArgumentException("Invalid thread priority value " + priority + "."); + this.priority = priority; + nativeSetPriority(priority); + } + + /** Get this Thread's priority. + ** @return the Thread's priority. + **/ + public final int getPriority() { + return priority; + } + + /** Set this Thread's name. + ** @param name the new name for this Thread. + ** @exception SecurityException if you cannot modify this Thread. + **/ + public final void setName(String name) { + checkAccess(); + this.name = name; + } + + /** Get this Thread's name. + ** @return this Thread's name. + **/ + public final String getName() { + return name; + } + + /** Get the ThreadGroup this Thread belongs to. + ** @return this Thread's ThreadGroup. + **/ + public final ThreadGroup getThreadGroup() { + return group; + } + + /** Set the daemon status of this Thread. If this is a + ** daemon Thread, then the VM may exit even if it is still + ** running. This may only be called when the Thread is not + ** running. + ** + ** @specnote It is possible that this should only be called + ** if the Thread has not been started. This + ** interpretation was easier to implement, though, + ** so it's the one I chose :) + ** @param daemon whether this should be a daemon thread or not. + ** @exception SecurityException if you cannot modify this Thread. + ** @exception IllegalThreadStateException if the Thread is active. + **/ + public final void setDaemon(boolean daemon) { + this.daemon = daemon; + } + + /** Tell whether this is a daemon Thread or not. + ** @return whether this is a daemon Thread or not. + **/ + public final boolean isDaemon() { + return daemon; + } + + + /** Get the number of active threads in the current Thread's + ** ThreadGroup. This implementation calls + ** <CODE>currentThread().getThreadGroup().activeCount()</CODE>. + ** @return the number of active threads in the current Thread's + ** ThreadGroup. + **/ + public static int activeCount() { + return currentThread().group.activeCount(); + } + + /** Copy every active thread in the current Thread's ThreadGroup + ** into the array. This implementation calls + ** <CODE>getThreadGroup().enumerate(array)</CODE> + ** @param array the array to place the Threads into. + ** @return the number of Threads placed into the array. + **/ + public static int enumerate(Thread[] array) { + return currentThread().group.enumerate(array); + } + + /** Count the number of stack frames in this Thread. The Thread + ** in question must be suspended when this occurs. + ** + ** @return the number of stack frames in this Thread. + ** @exception IllegalThreadStateException if this Thread is + ** not suspended. + **/ + public native int countStackFrames(); + + + /** Determine whether the current Thread has been interrupted. + ** @return whether the current Thread has been interrupted. + **/ + public static boolean interrupted() { + return currentThread().isInterrupted(); + } + + /** Determine whether this Thread has been interrupted. + ** @return whether this Thread has been interrupted. + **/ + public native boolean isInterrupted(); + + /** Determine whether this Thread is alive. + ** @return whether this Thread is alive. + **/ + public final native boolean isAlive(); + + + /** Check whether the current Thread is allowed to + ** modify this Thread. + ** @exception SecurityException if the current Thread cannot + ** modify this Thread. + **/ + public void checkAccess() { + SecurityManager sm = System.getSecurityManager(); + if(sm != null) { + sm.checkAccess(this); + } + } + + /** Return a human-readable String representing this Thread. + ** @return a human-readable String representing this Thread. + ** @XXX determine the exact format of this String. + **/ + public String toString() { + return ""; + } + + final native void nativeInit(); + final native void nativeStop(Throwable t); + final native void nativeInterrupt(); + final native void nativeDestroy(); + final native void nativeSuspend(); + final native void nativeResume(); + final native void nativeSetPriority(int newPriority); +} |