001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package java.lang;
028:
029: /**
030: * A <i>thread</i> is a thread of execution in a program. The Java
031: * Virtual Machine allows an application to have multiple threads of
032: * execution running concurrently.
033: * <p>
034: * Every thread has a priority. Threads with higher priority are
035: * executed in preference to threads with lower priority.
036: * <p>
037: * There are two ways to create a new thread of execution. One is to
038: * declare a class to be a subclass of <code>Thread</code>. This
039: * subclass should override the <code>run</code> method of class
040: * <code>Thread</code>. An instance of the subclass can then be
041: * allocated and started. For example, a thread that computes primes
042: * larger than a stated value could be written as follows:
043: * <p><hr><blockquote><pre>
044: * class PrimeThread extends Thread {
045: * long minPrime;
046: * PrimeThread(long minPrime) {
047: * this.minPrime = minPrime;
048: * }
049: *
050: * public void run() {
051: * // compute primes larger than minPrime
052: * . . .
053: * }
054: * }
055: * </pre></blockquote><hr>
056: * <p>
057: * The following code would then create a thread and start it running:
058: * <p><blockquote><pre>
059: * PrimeThread p = new PrimeThread(143);
060: * p.start();
061: * </pre></blockquote>
062: * <p>
063: * The other way to create a thread is to declare a class that
064: * implements the <code>Runnable</code> interface. That class then
065: * implements the <code>run</code> method. An instance of the class can
066: * then be allocated, passed as an argument when creating
067: * <code>Thread</code>, and started. The same example in this other
068: * style looks like the following:
069: * <p><hr><blockquote><pre>
070: * class PrimeRun implements Runnable {
071: * long minPrime;
072: * PrimeRun(long minPrime) {
073: * this.minPrime = minPrime;
074: * }
075: *
076: * public void run() {
077: * // compute primes larger than minPrime
078: * . . .
079: * }
080: * }
081: * </pre></blockquote><hr>
082: * <p>
083: * The following code would then create a thread and start it running:
084: * <p><blockquote><pre>
085: * PrimeRun p = new PrimeRun(143);
086: * new Thread(p).start();
087: * </pre></blockquote>
088: * <p>
089: *
090: *
091: * @version 12/17/01 (CLDC 1.1)
092: * @see java.lang.Runnable
093: * @see java.lang.Runtime#exit(int)
094: * @see java.lang.Thread#run()
095: * @since JDK1.0, CLDC 1.0
096: */
097: public class Thread implements Runnable {
098:
099: /* Thread priority */
100: private int priority = NORM_PRIORITY;
101:
102: /* What will be run. */
103: private Runnable target;
104:
105: /*
106: * This private variable is used by the VM.
107: * Users never see it.
108: */
109: private Object vm_thread;
110: private int is_terminated;
111: private int is_stillborn;
112:
113: /* Thread name */
114: private char name[];
115:
116: /**
117: * The minimum priority that a thread can have.
118: */
119: public final static int MIN_PRIORITY = 1;
120:
121: /**
122: * The default priority that is assigned to a thread.
123: */
124: public final static int NORM_PRIORITY = 5;
125:
126: /**
127: * The maximum priority that a thread can have.
128: */
129: public final static int MAX_PRIORITY = 10;
130:
131: /**
132: * Returns a reference to the currently executing
133: * <code>Thread</code> object.
134: *
135: * @return the currently executing thread.
136: */
137: public static native Thread currentThread();
138:
139: /* For autonumbering anonymous threads. */
140: private static int threadInitNumber;
141:
142: private static synchronized int nextThreadNum() {
143: return ++threadInitNumber;
144: }
145:
146: /**
147: * Causes the currently executing thread object
148: * to temporarily pause and allow other threads to execute.
149: */
150: public static native void yield();
151:
152: /**
153: * Causes the currently executing thread to sleep (temporarily cease
154: * execution) for the specified number of milliseconds. The thread
155: * does not lose ownership of any monitors.
156: *
157: * @param millis the length of time to sleep in milliseconds.
158: * @exception InterruptedException if another thread has interrupted
159: * the current thread. The <i>interrupted status</i> of the
160: * current thread is cleared when this exception is thrown.
161: * @see java.lang.Object#notify()
162: */
163: public static native void sleep(long millis)
164: throws InterruptedException;
165:
166: /**
167: * Initialize a Thread.
168: *
169: * @param target the object whose run() method gets called
170: * @param name the name of the new thread
171: */
172:
173: private void init(Runnable target, String name) {
174: Thread parent = currentThread();
175: this .target = target;
176: this .name = name.toCharArray();
177: this .priority = parent.getPriority();
178: setPriority(priority);
179: }
180:
181: /**
182: * Allocates a new <code>Thread</code> object.
183: * <p>
184: * Threads created this way must have overridden their
185: * <code>run()</code> method to actually do anything.
186: *
187: * @see java.lang.Runnable
188: */
189: public Thread() {
190: init(null, "Thread-" + nextThreadNum());
191: }
192:
193: /**
194: * Allocates a new <code>Thread</code> object with the
195: * given name.
196: *
197: * Threads created this way must have overridden their
198: * <code>run()</code> method to actually do anything.
199: *
200: * @param name the name of the new thread.
201: */
202: public Thread(String name) {
203: init(null, name);
204: }
205:
206: /**
207: * Allocates a new <code>Thread</code> object with a
208: * specific target object whose <code>run</code> method
209: * is called.
210: *
211: * @param target the object whose <code>run</code> method is called.
212: */
213: public Thread(Runnable target) {
214: init(target, "Thread-" + nextThreadNum());
215: }
216:
217: /**
218: * Allocates a new <code>Thread</code> object with the given
219: * target and name.
220: *
221: * @param target the object whose <code>run</code> method is called.
222: * @param name the name of the new thread.
223: */
224: public Thread(Runnable target, String name) {
225: init(target, name);
226: }
227:
228: /**
229: * Causes this thread to begin execution; the Java Virtual Machine
230: * calls the <code>run</code> method of this thread.
231: * <p>
232: * The result is that two threads are running concurrently: the
233: * current thread (which returns from the call to the
234: * <code>start</code> method) and the other thread (which executes its
235: * <code>run</code> method).
236: *
237: * @exception IllegalThreadStateException if the thread was already
238: * started.
239: * @see java.lang.Thread#run()
240: */
241: public synchronized void start() {
242: start(this );
243: }
244:
245: private static synchronized void start(Thread thread) {
246: thread.start0();
247: }
248:
249: private native void start0();
250:
251: /**
252: * If this thread was constructed using a separate
253: * <code>Runnable</code> run object, then that
254: * <code>Runnable</code> object's <code>run</code> method is called;
255: * otherwise, this method does nothing and returns.
256: * <p>
257: * Subclasses of <code>Thread</code> should override this method.
258: *
259: * @see java.lang.Thread#start()
260: * @see java.lang.Runnable#run()
261: */
262: public void run() {
263: if (target != null) {
264: target.run();
265: }
266: }
267:
268: /**
269: * Interrupts this thread. In an implementation conforming
270: * to the CLDC Specification, this operation is not
271: * required to cancel or clean up any pending I/O operations
272: * that the thread may be waiting for.
273: *
274: * @since JDK 1.0, CLDC 1.1
275: */
276: public void interrupt() {
277: interrupt0();
278: }
279:
280: /**
281: * Tests if this thread is alive. A thread is alive if it has
282: * been started and has not yet died.
283: *
284: * @return <code>true</code> if this thread is alive;
285: * <code>false</code> otherwise.
286: */
287: public final native boolean isAlive();
288:
289: /**
290: * Changes the priority of this thread.
291: *
292: * @param newPriority priority to set this thread to
293: * @exception IllegalArgumentException If the priority is not in the
294: * range <code>MIN_PRIORITY</code> to
295: * <code>MAX_PRIORITY</code>.
296: * @see java.lang.Thread#getPriority()
297: * @see java.lang.Thread#MAX_PRIORITY
298: * @see java.lang.Thread#MIN_PRIORITY
299: */
300: public final void setPriority(int newPriority) {
301: if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
302: throw new IllegalArgumentException();
303: }
304: setPriority0(priority, newPriority);
305: priority = newPriority;
306: }
307:
308: /**
309: * Returns this thread's priority.
310: *
311: * @return this thread's priority.
312: * @see java.lang.Thread#setPriority(int)
313: */
314: public final int getPriority() {
315: return priority;
316: }
317:
318: /**
319: * Returns this thread's name. Note that in CLDC the name
320: * of the thread can only be set when creating the thread.
321: *
322: * @return this thread's name.
323: */
324: public final String getName() {
325: return String.valueOf(name);
326: }
327:
328: /**
329: * Returns the current number of active threads in the virtual machine.
330: *
331: * @return the current number of active threads.
332: */
333: public static native int activeCount();
334:
335: /**
336: * Waits for this thread to die.
337: *
338: * @exception InterruptedException if another thread has interrupted
339: * the current thread. The <i>interrupted status</i> of the
340: * current thread is cleared when this exception is thrown.
341: */
342: public final synchronized void join() throws InterruptedException {
343: while (isAlive()) {
344: wait(1000);
345: }
346: }
347:
348: /**
349: * Returns a string representation of this thread, including the
350: * thread's name and priority.
351: *
352: * @return a string representation of this thread.
353: */
354: public String toString() {
355: return "Thread[" + getName() + "," + getPriority() + "]";
356: }
357:
358: /* Some private helper methods */
359: private native void setPriority0(int oldPriority, int newPriority);
360:
361: private native void interrupt0();
362:
363: private synchronized native void internalExit();
364:
365: }
|