OSDN Git Service

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