OSDN Git Service

34921677c8a67186dfbdd58bb7bd4f104eddea85
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / Thread.java
1 // Thread.java - Thread class.
2
3 /* Copyright (C) 1998, 1999  Red Hat, Inc.
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12
13 /**
14  * @author Tom Tromey <tromey@cygnus.com>
15  * @date August 24, 1998 
16  */
17
18 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
19  * "The Java Language Specification", ISBN 0-201-63451-1
20  * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
21  * Status:  Complete to version 1.1, with caveats
22  * Known problems:
23  *   No attempt was made to implement suspend/resume
24  *     (this could be done in some cases)
25  *   Various methods which assume a VM are likewise unimplemented
26  *   We do implement stop() even though it is deprecated.
27  */
28
29 public class Thread implements Runnable
30 {
31   public final static int MAX_PRIORITY = 10;
32   public final static int MIN_PRIORITY = 1;
33   public final static int NORM_PRIORITY = 5;
34
35   public static int activeCount ()
36   {
37     return currentThread().getThreadGroup().activeCount();
38   }
39
40   public void checkAccess ()
41   {
42     SecurityManager s = System.getSecurityManager();
43     if (s != null)
44       s.checkAccess(this);
45   }
46
47   public native int countStackFrames ();
48   public static native Thread currentThread ();
49   public native void destroy ();
50   public static native void dumpStack ();
51
52   public static int enumerate (Thread[] threads)
53   {
54     return currentThread().group.enumerate(threads);
55   }
56
57   public final String getName ()
58   {
59     return name;
60   }
61
62   public final int getPriority ()
63   {
64     return priority;
65   }
66
67   public final ThreadGroup getThreadGroup ()
68   {
69     return group;
70   }
71
72   public native void interrupt ();
73
74   public static boolean interrupted ()
75   {
76     return currentThread().isInterrupted_();
77   }
78
79   // FIXME: it seems to me that this should be synchronized.
80   // Check the threads interrupted status. Note that this does not clear the
81   // threads interrupted status (per JDK 1.2 online API documentation).
82   public boolean isInterrupted ()
83   {
84     return interrupt_flag;
85   }
86
87   public final boolean isAlive ()
88   {
89     return alive_flag;
90   }
91
92   public final boolean isDaemon ()
93   {
94     return daemon_flag;
95   }
96
97   public final void join () throws InterruptedException
98   {
99     join (0, 0);
100   }
101
102   public final void join (long timeout) throws InterruptedException
103   {
104     join (timeout, 0);
105   }
106
107   public final native void join (long timeout, int nanos)
108     throws InterruptedException;
109
110   public final native void resume ();
111
112   // This method exists only to avoid a warning from the C++ compiler.
113   private static final native void run__ (Object obj);
114   private native final void finish_ ();
115
116   // Convenience method to check and clear the thread's interrupted status.  
117   private boolean isInterrupted_ ()
118   {
119     boolean r = interrupt_flag;
120     interrupt_flag = false;
121     return r;
122   }
123   
124   private final void run_ ()
125   {
126     try
127       {
128         run ();
129       }
130     catch (Throwable e)
131       {
132         // Uncaught exceptions are forwarded to the ThreadGroup.  If
133         // this results in an uncaught exception, that is ignored.
134         try
135           {
136             group.uncaughtException(this, e);
137           }
138         catch (Throwable f)
139           {
140             // Nothing.
141           }
142       }
143     finish_ ();
144   }
145
146   public void run ()
147   {
148     if (runnable != null)
149       runnable.run();
150   }
151
152   public final void setDaemon (boolean status)
153   {
154     checkAccess ();
155     if (isAlive ())
156       throw new IllegalThreadStateException ();
157     daemon_flag = status;
158   }
159
160   // TODO12:
161   // public ClassLoader getContextClassLoader()
162   // {
163   // }
164
165   // TODO12:
166   // public void setContextClassLoader(ClassLoader cl)
167   // {
168   // }
169
170   public final void setName (String n)
171   {
172     checkAccess ();
173     // The Class Libraries book says ``threadName cannot be null''.  I
174     // take this to mean NullPointerException.
175     if (n == null)
176       throw new NullPointerException ();
177     name = n;
178   }
179
180   public final native void setPriority (int newPriority);
181
182   public static void sleep (long timeout) throws InterruptedException
183   {
184     sleep (timeout, 0);
185   }
186
187   public static native void sleep (long timeout, int nanos)
188     throws InterruptedException;
189   public synchronized native void start ();
190
191   public final void stop ()
192   {
193     // Argument doesn't matter, because this is no longer
194     // supported.
195     stop (null);
196   }
197
198   public final synchronized native void stop (Throwable e);
199   public final native void suspend ();
200
201   private final native void initialize_native ();
202
203   private final synchronized static String gen_name ()
204   {
205     String n;
206     n = "Thread-" + nextThreadNumber;
207     ++nextThreadNumber;
208     return n;
209   }
210
211   public Thread (ThreadGroup g, Runnable r, String n)
212   {
213     // Note that CURRENT can be null when we are creating the very
214     // first thread.  That's why we check it below.
215     Thread current = currentThread ();
216
217     if (g != null)
218       {
219         // If CURRENT is null, then we are creating the first thread.
220         // In this case we don't do the security check.
221         if (current != null)
222           g.checkAccess();
223       }
224     else
225       g = current.getThreadGroup();
226
227     // The Class Libraries book says ``threadName cannot be null''.  I
228     // take this to mean NullPointerException.
229     if (n == null)
230       throw new NullPointerException ();
231
232     name = n;
233     group = g;
234     g.add(this);
235     runnable = r;
236
237     data = null;
238     interrupt_flag = false;
239     alive_flag = false;
240     if (current != null)
241       {
242         daemon_flag = current.isDaemon();
243         priority = current.getPriority();
244       }
245     else
246       {
247         daemon_flag = false;
248         priority = NORM_PRIORITY;
249       }
250
251     initialize_native ();
252   }
253
254   public Thread ()
255   {
256     this (null, null, gen_name ());
257   }
258
259   public Thread (Runnable r)
260   {
261     this (null, r, gen_name ());
262   }
263
264   public Thread (String n)
265   {
266     this (null, null, n);
267   }
268
269   public Thread (ThreadGroup g, Runnable r)
270   {
271     this (g, r, gen_name ());
272   }
273
274   public Thread (ThreadGroup g, String n)
275   {
276     this (g, null, n);
277   }
278
279   public Thread (Runnable r, String n)
280   {
281     this (null, r, n);
282   }
283
284   public String toString ()
285   {
286     return "Thread[" + name + "," + priority + "," + group.getName() + "]";
287   }
288
289   public static native void yield ();
290
291   // Private data.
292   private ThreadGroup group;
293   private String name;
294   private Runnable runnable;
295   private int priority;
296   private boolean daemon_flag;
297   private boolean interrupt_flag;
298   private boolean alive_flag;
299
300   // This is a bit odd.  We need a way to represent some data that is
301   // manipulated only by the native side of this class.  We represent
302   // it as a Java object reference.  However, it is not actually a
303   // Java object.
304   private Object data;
305
306   // Next thread number to assign.
307   private static int nextThreadNumber = 0;
308 }