thread.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 467 行
JAVA
467 行
/*
* $Id: Thread.java,v 1.1 2003/11/25 11:42:00 epr Exp $
*/
package java.lang;
import org.jnode.vm.Unsafe;
import org.jnode.vm.VmSystem;
import org.jnode.vm.VmThread;
/**
* Kore implementation of the <code>java.lang.Thread</code> class.
* <p>
* All native methods are indirected through <code>java.lang.NativeLang</code>.
*
* @see java.lang.NativeLang
* @version Kore 0.0.3, June 1997
* @author Glynn Clements <a href="mailto:glynn@sensei.co.uk">glynn@sensei.co.uk</a>
* @author E. Prangsma (connection to JNode)
*/
public class Thread implements Runnable {
/** Is this a daemon thread? */
private boolean daemon;
/** The group this thread belongs to */
private final ThreadGroup group;
/** The name of this thread */
private String name;
/** A runnable target (if any) */
private final Runnable target;
/** The VM thread implementing this thread */
private final VmThread vmThread;
/** The context classloader of this thread */
private ClassLoader contextClassLoader;
/** The thread in which I was created */
private final Thread parent;
/**
* Number of threads created. Used only for generating "unique" names.
*
* @see java.lang.Thread#autoName()
*/
private static int count = 0;
public final static int MAX_PRIORITY = 10;
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
/**
* Gets the active number of threads in the current thread's thread group.
*
* @return the active number of threads in the current thread's thread group.
*/
public static int activeCount() {
return currentThread().getThreadGroup().activeCount();
}
/**
* Generate a "unique" default name for a thread.
*/
private static synchronized String autoName() {
return "Thread-" + (++count);
}
/**
* Gets the current thread.
*
* @return
*/
public static Thread currentThread() {
VmThread current = VmThread.currentThread();
if (current != null) {
return current.asThread();
} else {
return null;
}
}
/**
* Prints a stack trace of the current thread.
*/
public static void dumpStack() {
new Exception("Stack trace").printStackTrace();
}
public static int enumerate(Thread[] threads) {
return currentThread().getThreadGroup().enumerate(threads);
}
public static boolean interrupted() {
return currentThread().isInterrupted();
}
public static void sleep(long millis) throws InterruptedException {
sleep(millis, 0);
}
/*
* XXX needs to be synchronized to avoid losing interrupts? it checks and sets state, which
* should be protected...
*/
public static void sleep(long millis, int nanos) throws InterruptedException {
VmThread.currentThread().sleep(millis, nanos);
}
public final VmThread getVmThread() {
return vmThread;
}
public static void yield() {
VmThread.yield();
}
/**
* Create a new default instance
*
* @see java.lang.Object#Object()
*/
public Thread() {
this(null, null, autoName());
}
/**
* Create a new instance with a runnable as thread runner.
*
* @param target
*/
public Thread(Runnable target) {
this(null, target, autoName());
}
/**
* Create a new instance with a runnable as thread runner and a given name.
*
* @param target
* @param name
*/
public Thread(Runnable target, String name) {
this(null, target, name);
}
/**
* Create a new instance with a given name.
*
* @param name
*/
public Thread(String name) {
this(null, null, name);
}
/**
* Create a new instance with a given group as containing group and a runnable as thread
* runner.
*
* @param group
* @param target
*/
public Thread(ThreadGroup group, Runnable target) {
this(group, target, autoName());
}
/**
* Create a new instance with a given group as containing group, a runnable as thread runner
* and a given name.
*
* @param group
* @param target
* @param name
*/
public Thread(ThreadGroup group, Runnable target, String name) {
Thread current = currentThread();
if (group != null) {
group.checkAccess();
} else {
group = current.getThreadGroup();
}
if (group == null) {
throw new InternalError("Live thread has invalid group: " + name);
}
group.add(this);
this.group = group;
this.target = target;
this.name = name;
this.parent = current;
this.daemon = current.isDaemon();
this.vmThread = Unsafe.getCurrentProcessor().createThread(this);
this.vmThread.setPriority(current.getPriority());
}
/**
* Create a new instance with a given group as containing group and a given name.
*
* @param group
* @param name
*/
public Thread(ThreadGroup group, String name) {
this(group, null, name);
}
/**
* Create a new thread from a given VmThread. Only used for the main thread.
*
* @param vmThread
* @throws IllegalArgumentException
* If the given vmThread is not the root thread or the given vmThread already has
* an associated java thread.
*/
public Thread(VmThread vmThread) throws IllegalArgumentException {
if (vmThread.hasJavaThread()) {
throw new IllegalArgumentException("vmThread has already a java thread associated with it");
}
this.vmThread = vmThread;
this.group = ThreadGroup.getRootGroup();
this.group.add(this);
this.name = "System";
this.target = null;
this.parent = null;
}
/**
* Has the current execution context enough access to modify this object?
*/
public void checkAccess() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkAccess(this);
}
public int countStackFrames() {
return vmThread.countStackFrames();
}
/**
* Destroys this thread, without any cleanup. Any monitors it has locked remain locked. (This
* method is not implemented.)
*/
public void destroy() {
vmThread.destroy();
}
/**
* Method called only by the VM to let the object do some java-level cleanup.
*/
public final void onExit() {
if (vmThread.isStopping()) {
group.remove(this);
}
}
/**
* Gets the context classloader for this thread. The context ClassLoader is provided by the
* creator of the thread for use by code running in this thread when loading classes and
* resources. If not set, the default is the ClassLoader context of the parent Thread. The
* context ClassLoader of the primordial thread is typically set to the class loader used to
* load the application. First, if there is a security manager, and the caller's class loader
* is not null and the caller's class loader is not the same as or an ancestor of the context
* class loader for the thread whose context class loader is being requested, then the security
* manager's checkPermission method is called with a <code>RuntimePermission("getClassLoader")</code>
* permission to see if it's ok to get the context ClassLoader.
*
* @return
*/
public ClassLoader getContextClassLoader() {
if (contextClassLoader != null) {
return contextClassLoader;
} else if (parent != null) {
return parent.getContextClassLoader();
} else {
return getClass().getClassLoader();
}
}
/**
* Sets the context ClassLoader for this Thread. The context ClassLoader can be set when a
* thread is created, and allows the creator of the thread to provide the appropriate class
* loader to code running in the thread when loading classes and resources.
*
* First, if there is a security manager, its checkPermission method is called with a
* RuntimePermission("setContextClassLoader") permission to see if it's ok to set the context
* ClassLoader.
*
* @param loader
*/
public void setContextClassLoader(ClassLoader loader) throws SecurityException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.contextClassLoader = loader;
}
/**
* Gets the name of this thread
*
* @return
*/
public final String getName() {
return name;
}
/**
* Gets the priority of this thread
*
* @return
*/
public final int getPriority() {
return vmThread.getPriority();
}
/**
* Gets the group this thread is a child of.
*
* @return
*/
public final ThreadGroup getThreadGroup() {
return isAlive() ? group : null;
}
/**
* Interrupt this thread.
*/
public void interrupt() {
vmThread.interrupt();
}
/**
* Returns <code>true</code> if the thread represented by this object is running (including
* suspended, asleep, or interrupted.) Returns <code>false</code> if the thread hasn't be
* started yet, is stopped or destroyed.
*
* @return <code>true</code> if thread is alive, <code>false</code> if not.
* @see #start()
* @see #stop()
* @see #suspend()
* @see #interrupt()
*/
public final boolean isAlive() {
return vmThread.isAlive();
}
public final boolean isDaemon() {
return daemon;
}
public boolean isInterrupted() {
return vmThread.isInterrupted();
}
/**
* Is this thread waiting in a monitor?
*
* @return boolean
*/
public boolean isWaiting() {
return vmThread.isWaiting();
}
/**
* Is this thread in the running state?
*
* @return boolean
*/
public final boolean isRunning() {
return vmThread.isRunning() || vmThread.isYielding();
}
/**
* Join with the current thread. The calling thread will block until this thread dies.
*
* XXX wait()s on the thread. Seems like this would cause a spurious wakeup if some code
* synchronizes on the thread and uses wait/notify for some other purpose.
*/
public final synchronized void join() throws InterruptedException {
while (isAlive()) {
/* wait sets this.state = WAITING; */
wait();
/* wait sets this.state = RUNNING; */
}
}
public final synchronized void join(long millis) throws InterruptedException {
if (millis == 0) {
join();
} else {
final long stopTime = VmSystem.currentKernelMillis() + millis;
while (isAlive() && (millis > 0)) {
/* wait sets this.state = WAITING; */
wait(millis);
millis = stopTime - VmSystem.currentKernelMillis();
/* wait sets this.state = RUNNING; */
}
}
}
public final void join(long millis, int nanos) throws InterruptedException {
join(millis);
}
public final void resume() {
vmThread.resume();
}
public void run() {
if (target != null)
target.run();
}
public final void setDaemon(boolean daemon) {
checkAccess();
if (isAlive())
throw new IllegalThreadStateException("already started");
this.daemon = daemon;
}
public final void setName(String name) {
checkAccess();
this.name = name;
}
public final void setPriority(int priority) {
vmThread.setPriority(priority);
}
/**
* Start this thread object. After calling this method there will be a new active thread in the
* system (assuming things go well.) The <code>Runnable</code> object, or the Thread's <code>run()</code>
* method will be started in a new thread.
*
*/
public void start() {
vmThread.start();
}
public final void stop() {
vmThread.stop(new ThreadDeath());
}
/**
* The polite way to kill a thread.
*
* @param error
* <code>Throwable</code> to toss in stopped thread.
*/
public final void stop(Throwable error) {
checkAccess();
if (error == null) {
throw new NullPointerException("Throwable is null");
}
vmThread.stop(error);
}
public final void suspend() {
vmThread.suspend();
}
public String toString() {
return "Thread[" + name + "," + getPriority() + "," + group.getName() + "," + vmThread + "]";
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?