128 * <p>
129 * Unless otherwise noted, passing a {@code null} argument to a constructor
130 * or method in this class will cause a {@link NullPointerException} to be
131 * thrown.
132 *
133 * @author unascribed
134 * @see Runnable
135 * @see Runtime#exit(int)
136 * @see #run()
137 * @see #stop()
138 * @since 1.0
139 */
140 public
141 class Thread implements Runnable {
142 /* Make sure registerNatives is the first thing <clinit> does. */
143 private static native void registerNatives();
144 static {
145 registerNatives();
146 }
147
148 private volatile char name[];
149 private int priority;
150 private Thread threadQ;
151 private long eetop;
152
153 /* Whether or not to single_step this thread. */
154 private boolean single_step;
155
156 /* Whether or not the thread is a daemon thread. */
157 private boolean daemon = false;
158
159 /* JVM state */
160 private boolean stillborn = false;
161
162 /* What will be run. */
163 private Runnable target;
164
165 /* The group of this thread */
166 private ThreadGroup group;
167
168 /* The context ClassLoader for this thread */
349 init(g, target, name, stackSize, null);
350 }
351
352 /**
353 * Initializes a Thread.
354 *
355 * @param g the Thread group
356 * @param target the object whose run() method gets called
357 * @param name the name of the new Thread
358 * @param stackSize the desired stack size for the new thread, or
359 * zero to indicate that this parameter is to be ignored.
360 * @param acc the AccessControlContext to inherit, or
361 * AccessController.getContext() if null
362 */
363 private void init(ThreadGroup g, Runnable target, String name,
364 long stackSize, AccessControlContext acc) {
365 if (name == null) {
366 throw new NullPointerException("name cannot be null");
367 }
368
369 this.name = name.toCharArray();
370
371 Thread parent = currentThread();
372 SecurityManager security = System.getSecurityManager();
373 if (g == null) {
374 /* Determine if it's an applet or not */
375
376 /* If there is a security manager, ask the security manager
377 what to do. */
378 if (security != null) {
379 g = security.getThreadGroup();
380 }
381
382 /* If the security doesn't have a strong opinion of the matter
383 use the parent thread group. */
384 if (g == null) {
385 g = parent.getThreadGroup();
386 }
387 }
388
389 /* checkAccess regardless of whether or not threadgroup is
1102 public final int getPriority() {
1103 return priority;
1104 }
1105
1106 /**
1107 * Changes the name of this thread to be equal to the argument
1108 * <code>name</code>.
1109 * <p>
1110 * First the <code>checkAccess</code> method of this thread is called
1111 * with no arguments. This may result in throwing a
1112 * <code>SecurityException</code>.
1113 *
1114 * @param name the new name for this thread.
1115 * @exception SecurityException if the current thread cannot modify this
1116 * thread.
1117 * @see #getName
1118 * @see #checkAccess()
1119 */
1120 public final synchronized void setName(String name) {
1121 checkAccess();
1122 this.name = name.toCharArray();
1123 if (threadStatus != 0) {
1124 setNativeName(name);
1125 }
1126 }
1127
1128 /**
1129 * Returns this thread's name.
1130 *
1131 * @return this thread's name.
1132 * @see #setName(String)
1133 */
1134 public final String getName() {
1135 return new String(name, true);
1136 }
1137
1138 /**
1139 * Returns the thread group to which this thread belongs.
1140 * This method returns null if this thread has died
1141 * (been stopped).
1142 *
1143 * @return this thread's thread group.
1144 */
1145 public final ThreadGroup getThreadGroup() {
1146 return group;
1147 }
1148
1149 /**
1150 * Returns an estimate of the number of active threads in the current
1151 * thread's {@linkplain java.lang.ThreadGroup thread group} and its
1152 * subgroups. Recursively iterates over all subgroups in the current
1153 * thread's thread group.
1154 *
1155 * <p> The value returned is only an estimate because the number of
|
128 * <p>
129 * Unless otherwise noted, passing a {@code null} argument to a constructor
130 * or method in this class will cause a {@link NullPointerException} to be
131 * thrown.
132 *
133 * @author unascribed
134 * @see Runnable
135 * @see Runtime#exit(int)
136 * @see #run()
137 * @see #stop()
138 * @since 1.0
139 */
140 public
141 class Thread implements Runnable {
142 /* Make sure registerNatives is the first thing <clinit> does. */
143 private static native void registerNatives();
144 static {
145 registerNatives();
146 }
147
148 private volatile String name;
149 private int priority;
150 private Thread threadQ;
151 private long eetop;
152
153 /* Whether or not to single_step this thread. */
154 private boolean single_step;
155
156 /* Whether or not the thread is a daemon thread. */
157 private boolean daemon = false;
158
159 /* JVM state */
160 private boolean stillborn = false;
161
162 /* What will be run. */
163 private Runnable target;
164
165 /* The group of this thread */
166 private ThreadGroup group;
167
168 /* The context ClassLoader for this thread */
349 init(g, target, name, stackSize, null);
350 }
351
352 /**
353 * Initializes a Thread.
354 *
355 * @param g the Thread group
356 * @param target the object whose run() method gets called
357 * @param name the name of the new Thread
358 * @param stackSize the desired stack size for the new thread, or
359 * zero to indicate that this parameter is to be ignored.
360 * @param acc the AccessControlContext to inherit, or
361 * AccessController.getContext() if null
362 */
363 private void init(ThreadGroup g, Runnable target, String name,
364 long stackSize, AccessControlContext acc) {
365 if (name == null) {
366 throw new NullPointerException("name cannot be null");
367 }
368
369 this.name = name;
370
371 Thread parent = currentThread();
372 SecurityManager security = System.getSecurityManager();
373 if (g == null) {
374 /* Determine if it's an applet or not */
375
376 /* If there is a security manager, ask the security manager
377 what to do. */
378 if (security != null) {
379 g = security.getThreadGroup();
380 }
381
382 /* If the security doesn't have a strong opinion of the matter
383 use the parent thread group. */
384 if (g == null) {
385 g = parent.getThreadGroup();
386 }
387 }
388
389 /* checkAccess regardless of whether or not threadgroup is
1102 public final int getPriority() {
1103 return priority;
1104 }
1105
1106 /**
1107 * Changes the name of this thread to be equal to the argument
1108 * <code>name</code>.
1109 * <p>
1110 * First the <code>checkAccess</code> method of this thread is called
1111 * with no arguments. This may result in throwing a
1112 * <code>SecurityException</code>.
1113 *
1114 * @param name the new name for this thread.
1115 * @exception SecurityException if the current thread cannot modify this
1116 * thread.
1117 * @see #getName
1118 * @see #checkAccess()
1119 */
1120 public final synchronized void setName(String name) {
1121 checkAccess();
1122 if (name == null) {
1123 throw new NullPointerException("name cannot be null");
1124 }
1125
1126 this.name = name;
1127 if (threadStatus != 0) {
1128 setNativeName(name);
1129 }
1130 }
1131
1132 /**
1133 * Returns this thread's name.
1134 *
1135 * @return this thread's name.
1136 * @see #setName(String)
1137 */
1138 public final String getName() {
1139 return name;
1140 }
1141
1142 /**
1143 * Returns the thread group to which this thread belongs.
1144 * This method returns null if this thread has died
1145 * (been stopped).
1146 *
1147 * @return this thread's thread group.
1148 */
1149 public final ThreadGroup getThreadGroup() {
1150 return group;
1151 }
1152
1153 /**
1154 * Returns an estimate of the number of active threads in the current
1155 * thread's {@linkplain java.lang.ThreadGroup thread group} and its
1156 * subgroups. Recursively iterates over all subgroups in the current
1157 * thread's thread group.
1158 *
1159 * <p> The value returned is only an estimate because the number of
|