`

Runnable and Thread

阅读更多

今天看了源码,总算多少理解一点,对Runnable 和 Thread的区别

 

一句话,Runnable是接口,Thread 继承了Runnable, 它们都有run()方法。

 

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used 
     * to create a thread, starting the thread causes the object's 
     * <code>run</code> method to be called in that separately executing 
     * thread. 
     * <p>
     * The general contract of the method <code>run</code> is that it may 
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

 

public class Thread implements Runnable {
	/* Make sure registerNatives is the first thing <clinit> does. */
	private static native void registerNatives();

	static {
		registerNatives();
	}

	private char name[];
	private int priority;
	private Thread threadQ;
	private long eetop;

	/* Whether or not to single_step this thread. */
	private boolean single_step;

	/* Whether or not the thread is a daemon thread. */
	private boolean daemon = false;

	/* JVM state */
	private boolean stillborn = false;

	/* What will be run. */
	private Runnable target;

	/* The group of this thread */
	private ThreadGroup group;

	/* The context ClassLoader for this thread */
	private ClassLoader contextClassLoader;

	/* The inherited AccessControlContext of this thread */
	private AccessControlContext inheritedAccessControlContext;

	/* For autonumbering anonymous threads. */
	private static int threadInitNumber;

	private static synchronized int nextThreadNum() {
		return threadInitNumber++;
	}

	ThreadLocal.ThreadLocalMap threadLocals = null;
	ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

	/*
	 * The requested stack size for this thread, or 0 if the creator did not
	 * specify a stack size. It is up to the VM to do whatever it likes with
	 * this number; some VMs will ignore it.
	 */
	private long stackSize;

	/*
	 * JVM-private state that persists after native thread termination.
	 */
	private long nativeParkEventPointer;

	private long tid;
	private int threadStatus = 0;
	
	/* For generating thread ID */
	private static long threadSeqNumber;
	private static synchronized long nextThreadID() {
		return ++threadSeqNumber;
	}

	/**
	 * The argument supplied to the current call to
	 * java.util.concurrent.locks.LockSupport.park. Set by (private)
	 * java.util.concurrent.locks.LockSupport.setBlocker Accessed using
	 * java.util.concurrent.locks.LockSupport.getBlocker
	 */
	volatile Object parkBlocker;

	/*
	 * The object in which this thread is blocked in an interruptible I/O
	 * operation, if any. The blocker's interrupt method should be invoked after
	 * setting this thread's interrupt status.
	 */
	private volatile Interruptible blocker;
	private Object blockerLock = new Object();

	/*
	 * Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio
	 * code
	 */
	void blockedOn(Interruptible b) {
		synchronized (blockerLock) {
			blocker = b;
		}
	}

	public final static int MIN_PRIORITY = 1;
	public final static int NORM_PRIORITY = 5;
	public final static int MAX_PRIORITY = 10;

	/* If stop was called before start */
	private boolean stopBeforeStart;

	/* Remembered Throwable from stop before start */
	private Throwable throwableFromStop;

	/**
	 * Returns a reference to the currently executing thread object.
	 * 
	 * @return the currently executing thread.
	 */
	public static native Thread currentThread();

	/**
	 * Causes the currently executing thread object to temporarily pause and
	 * allow other threads to execute.
	 */
	public static native void yield();

	/**
	 * Causes the currently executing thread to sleep (temporarily cease
	 * execution) for the specified number of milliseconds, subject to the
	 * precision and accuracy of system timers and schedulers. The thread does
	 * not lose ownership of any monitors.
	 * 
	 * @param millis
	 *            the length of time to sleep in milliseconds.
	 * @exception InterruptedException
	 *                if any thread has interrupted the current thread. The
	 *                <i>interrupted status</i> of the current thread is cleared
	 *                when this exception is thrown.
	 * @see Object#notify()
	 */
	public static native void sleep(long millis) throws InterruptedException;

	/**
	 * Causes the currently executing thread to sleep (cease execution) for the
	 * specified number of milliseconds plus the specified number of
	 * nanoseconds, subject to the precision and accuracy of system timers and
	 * schedulers. The thread does not lose ownership of any monitors.
	 * 
	 * @param millis
	 *            the length of time to sleep in milliseconds.
	 * @param nanos
	 *            0-999999 additional nanoseconds to sleep.
	 * ...
	 */
	public static void sleep(long millis, int nanos)
			throws InterruptedException {
		if (millis < 0) {
			throw new IllegalArgumentException("timeout value is negative");
		}

		if (nanos < 0 || nanos > 999999) {
			throw new IllegalArgumentException(
					"nanosecond timeout value out of range");
		}

		if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
			millis++;
		}

		sleep(millis);
	}

	/**
	 * Initializes a Thread.
	 * ...
	 */
	private void init(ThreadGroup g, Runnable target, String name,
			long stackSize) {
		Thread parent = currentThread();
		SecurityManager security = System.getSecurityManager();
		if (g == null) {
			
			if (security != null) {
				g = security.getThreadGroup();
			}

			if (g == null) {
				g = parent.getThreadGroup();
			}
		}

		/*
		 * checkAccess regardless of whether or not threadgroup is explicitly
		 * passed in.
		 */
		g.checkAccess();

		/*
		 * Do we have the required permissions?
		 */
		if (security != null) {
			if (isCCLOverridden(getClass())) {
				security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
			}
		}

		g.addUnstarted();

		this.group = g;
		this.daemon = parent.isDaemon();
		this.priority = parent.getPriority();
		this.name = name.toCharArray();
		if (security == null || isCCLOverridden(parent.getClass()))
			this.contextClassLoader = parent.getContextClassLoader();
		else
			this.contextClassLoader = parent.contextClassLoader;
		this.inheritedAccessControlContext = AccessController.getContext();
		this.target = target;
		setPriority(priority);
		if (parent.inheritableThreadLocals != null)
			this.inheritableThreadLocals = ThreadLocal
					.createInheritedMap(parent.inheritableThreadLocals);
		/* Stash the specified stack size in case the VM cares */
		this.stackSize = stackSize;

		/* Set thread ID */
		tid = nextThreadID();
	}

	public Thread() {
		init(null, null, "Thread-" + nextThreadNum(), 0);
	}

	public Thread(Runnable target) {
		init(null, target, "Thread-" + nextThreadNum(), 0);
	}

	public Thread(ThreadGroup group, Runnable target) {
		init(group, target, "Thread-" + nextThreadNum(), 0);
	}

	public Thread(String name) {
		init(null, null, name, 0);
	}

	public Thread(ThreadGroup group, String name) {
		init(group, null, name, 0);
	}

	public Thread(Runnable target, String name) {
		init(null, target, name, 0);
	}

	public Thread(ThreadGroup group, Runnable target, String name) {
		init(group, target, name, 0);
	}

	public Thread(ThreadGroup group, Runnable target, String name,
			long stackSize) {
		init(group, target, name, stackSize);
	}

	/**
	 * Causes this thread to begin execution; the Java Virtual Machine calls the
	 * <code>run</code> method of this thread.
	 * <p>
	 * The result is that two threads are running concurrently: the current
	 * thread (which returns from the call to the <code>start</code> method) and
	 * the other thread (which executes its <code>run</code> method).
	 * <p>
	 * It is never legal to start a thread more than once. In particular, a
	 * thread may not be restarted once it has completed execution.
	 * 
	 * @exception IllegalThreadStateException
	 *                if the thread was already started.
	 * @see #run()
	 * @see #stop()
	 */
	public synchronized void start() {
		/**
		 * This method is not invoked for the main method thread or "system"
		 * group threads created/set up by the VM. Any new functionality added
		 * to this method in the future may have to also be added to the VM.
		 * 
		 * A zero status value corresponds to state "NEW".
		 */
		if (threadStatus != 0)
			throw new IllegalThreadStateException();
		group.add(this);
		start0();
		if (stopBeforeStart) {
			stop0(throwableFromStop);
		}
	}

	private native void start0();

	/**
	 * If this thread was constructed using a separate <code>Runnable</code> run
	 * object, then that <code>Runnable</code> object's <code>run</code> method
	 * is called; otherwise, this method does nothing and returns.
	 * <p>
	 * Subclasses of <code>Thread</code> should override this method.
	 * 
	 * @see #start()
	 * @see #stop()
	 * @see #Thread(ThreadGroup, Runnable, String)
	 */
	public void run() {
		if (target != null) {
			target.run();
		}
	}

	/**
	 * This method is called by the system to give a Thread a chance to clean up
	 * before it actually exits.
	 */
	private void exit() {
		if (group != null) {
			group.remove(this);
			group = null;
		}
		/* Aggressively null out all reference fields: see bug 4006245 */
		target = null;
		/* Speed the release of some of these resources */
		threadLocals = null;
		inheritableThreadLocals = null;
		inheritedAccessControlContext = null;
		blocker = null;
		uncaughtExceptionHandler = null;
	}

    @Deprecated
    public final void stop() {
        // If the thread is already dead, return.
	// A zero status value corresponds to "NEW".
	if ((threadStatus != 0) && !isAlive()) {
	    return;
	}
	stop1(new ThreadDeath());
    }
	
	@Deprecated
	public final synchronized void stop(Throwable obj) {
		stop1(obj);
	}

	/**
	 * Common impl for stop() and stop(Throwable).
	 */
	private final synchronized void stop1(Throwable th) {
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			checkAccess();
			if ((this != Thread.currentThread())
					|| (!(th instanceof ThreadDeath))) {
				security
						.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
			}
		}
		// A zero status value corresponds to "NEW"
		if (threadStatus != 0) {
			resume(); // Wake up thread if it was suspended; no-op otherwise
			stop0(th);
		} else {

			// Must do the null arg check that the VM would do with stop0
			if (th == null) {
				throw new NullPointerException();
			}

			// Remember this stop attempt for if/when start is used
			stopBeforeStart = true;
			throwableFromStop = th;
		}
	}

	/**
	 * Interrupts this thread.
	 * 
	 * <p>
	 * Unless the current thread is interrupting itself, which is always
	 * permitted, the {@link #checkAccess() checkAccess} method of this thread
	 * is invoked, which may cause a {@link SecurityException} to be thrown.
	 * 
	 * <p>
	 * If this thread is blocked in an invocation of the {@link Object#wait()
	 * wait()}, {@link Object#wait(long) wait(long)}, or
	 * {@link Object#wait(long, int) wait(long, int)} methods of the
	 * {@link Object} class, or of the {@link #join()}, {@link #join(long)},
	 * {@link #join(long, int)}, {@link #sleep(long)}, or
	 * {@link #sleep(long, int)}, methods of this class, then its interrupt
	 * status will be cleared and it will receive an
	 * {@link InterruptedException}.
	 * 
	 * <p>
	 * If this thread is blocked in an I/O operation upon an
	 * {@link java.nio.channels.InterruptibleChannel </code>interruptible
	 * channel<code>} then the channel will be closed, the thread's interrupt
	 * status will be set, and the thread will receive a
	 * {@link java.nio.channels.ClosedByInterruptException}.
	 * 
	 * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
	 * then the thread's interrupt status will be set and it will return
	 * immediately from the selection operation, possibly with a non-zero value,
	 * just as if the selector's {@link java.nio.channels.Selector#wakeup
	 * wakeup} method were invoked.
	 * 
	 * <p> If none of the previous conditions hold then this thread's interrupt
	 * status will be set.
	 * </p>
	 * 
	 * <p>
	 * Interrupting a thread that is not alive need not have any effect.
	 * 
	 * @throws SecurityException
	 *             if the current thread cannot modify this thread
	 * 
	 * @revised 6.0
	 * @spec JSR-51
	 */
	public void interrupt() {
		if (this != Thread.currentThread())
			checkAccess();

		synchronized (blockerLock) {
			Interruptible b = blocker;
			if (b != null) {
				interrupt0(); // Just to set the interrupt flag
				b.interrupt();
				return;
			}
		}
		interrupt0();
	}

	/**
	 * Tests whether the current thread has been interrupted. The <i>interrupted
	 * status</i> of the thread is cleared by this method. In other words, if
	 * this method were to be called twice in succession, the second call would
	 * return false (unless the current thread were interrupted again, after the
	 * first call had cleared its interrupted status and before the second call
	 * had examined it).
	 * 
	 * <p>
	 * A thread interruption ignored because a thread was not alive at the time
	 * of the interrupt will be reflected by this method returning false.
	 * 
	 * @return <code>true</code> if the current thread has been interrupted;
	 *         <code>false</code> otherwise.
	 * @see #isInterrupted()
	 * @revised 6.0
	 */
	public static boolean interrupted() {
		return currentThread().isInterrupted(true);
	}

	/**
	 * Tests whether this thread has been interrupted. The <i>interrupted
	 * status</i> of the thread is unaffected by this method.
	 * 
	 * <p>
	 * A thread interruption ignored because a thread was not alive at the time
	 * of the interrupt will be reflected by this method returning false.
	 * 
	 * @return <code>true</code> if this thread has been interrupted;
	 *         <code>false</code> otherwise.
	 * @see #interrupted()
	 * @revised 6.0
	 */
	public boolean isInterrupted() {
		return isInterrupted(false);
	}

	/**
	 * Tests if some Thread has been interrupted. The interrupted state is reset
	 * or not based on the value of ClearInterrupted that is passed.
	 */
	private native boolean isInterrupted(boolean ClearInterrupted);

	@Deprecated
	public void destroy() {
		throw new NoSuchMethodError();
	}

	/**
	 * Tests if this thread is alive. A thread is alive if it has been started
	 * and has not yet died.
	 * 
	 * @return <code>true</code> if this thread is alive; <code>false</code>
	 *         otherwise.
	 */
	public final native boolean isAlive();

	@Deprecated
	public final void suspend() {
		checkAccess();
		suspend0();
	}

	@Deprecated
	public final void resume() {
		checkAccess();
		resume0();
	}

	/**
	 * Changes the priority of this thread.
	 * <p>
	 * First the <code>checkAccess</code> method of this thread is called with
	 * no arguments. This may result in throwing a
	 * <code>SecurityException</code>.
	 * <p>
	 * Otherwise, the priority of this thread is set to the smaller of the
	 * specified <code>newPriority</code> and the maximum permitted priority of
	 * the thread's thread group.
	 * 
	 * @param newPriority
	 *            priority to set this thread to
	 * @exception IllegalArgumentException
	 *                If the priority is not in the range
	 *                <code>MIN_PRIORITY</code> to <code>MAX_PRIORITY</code>.
	 * @exception SecurityException
	 *                if the current thread cannot modify this thread.
	 * @see #getPriority
	 * @see #checkAccess()
	 * @see #getThreadGroup()
	 * @see #MAX_PRIORITY
	 * @see #MIN_PRIORITY
	 * @see ThreadGroup#getMaxPriority()
	 */
	public final void setPriority(int newPriority) {
		ThreadGroup g;
		checkAccess();
		if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
			throw new IllegalArgumentException();
		}
		if ((g = getThreadGroup()) != null) {
			if (newPriority > g.getMaxPriority()) {
				newPriority = g.getMaxPriority();
			}
			setPriority0(priority = newPriority);
		}
	}

	/**
	 * Returns this thread's priority.
	 * 
	 * @return this thread's priority.
	 * @see #setPriority
	 */
	public final int getPriority() {
		return priority;
	}

	/**
	 * Changes the name of this thread to be equal to the argument
	 * <code>name</code>.
	 * <p>
	 * First the <code>checkAccess</code> method of this thread is called with
	 * no arguments. This may result in throwing a
	 * <code>SecurityException</code>.
	 * 
	 * @param name
	 *            the new name for this thread.
	 * @exception SecurityException
	 *                if the current thread cannot modify this thread.
	 * @see #getName
	 * @see #checkAccess()
	 */
	public final void setName(String name) {
		checkAccess();
		this.name = name.toCharArray();
	}

	/**
	 * Returns this thread's name.
	 * 
	 * @return this thread's name.
	 * @see #setName(String)
	 */
	public final String getName() {
		return String.valueOf(name);
	}

	/**
	 * Returns the thread group to which this thread belongs. This method
	 * returns null if this thread has died (been stopped).
	 * 
	 * @return this thread's thread group.
	 */
	public final ThreadGroup getThreadGroup() {
		return group;
	}

	/**
	 * Returns the number of active threads in the current thread's thread
	 * group.
	 * 
	 * @return the number of active threads in the current thread's thread
	 *         group.
	 */
	public static int activeCount() {
		return currentThread().getThreadGroup().activeCount();
	}

	/**
	 * Copies into the specified array every active thread in the current
	 * thread's thread group and its subgroups. This method simply calls the
	 * <code>enumerate</code> method of the current thread's thread group with
	 * the array argument.
	 * <p>
	 * First, if there is a security manager, that <code>enumerate</code> method
	 * calls the security manager's <code>checkAccess</code> method with the
	 * thread group as its argument. This may result in throwing a
	 * <code>SecurityException</code>.
	 * 
	 * @param tarray
	 *            an array of Thread objects to copy to
	 * @return the number of threads put into the array
	 * @exception SecurityException
	 *                if a security manager exists and its
	 *                <code>checkAccess</code> method doesn't allow the
	 *                operation.
	 * @see ThreadGroup#enumerate(Thread[])
	 * @see SecurityManager#checkAccess(ThreadGroup)
	 */
	public static int enumerate(Thread tarray[]) {
		return currentThread().getThreadGroup().enumerate(tarray);
	}

	@Deprecated
	public native int countStackFrames();

	/**
	 * Waits at most <code>millis</code> milliseconds for this thread to die. A
	 * timeout of <code>0</code> means to wait forever.
	 * 
	 * @param millis
	 *            the time to wait in milliseconds.
	 * @exception InterruptedException
	 *                if any thread has interrupted the current thread. The
	 *                <i>interrupted status</i> of the current thread is cleared
	 *                when this exception is thrown.
	 */
	public final synchronized void join(long millis)
			throws InterruptedException {
		long base = System.currentTimeMillis();
		long now = 0;

		if (millis < 0) {
			throw new IllegalArgumentException("timeout value is negative");
		}

		if (millis == 0) {
			while (isAlive()) {
				wait(0);
			}
		} else {
			while (isAlive()) {
				long delay = millis - now;
				if (delay <= 0) {
					break;
				}
				wait(delay);
				now = System.currentTimeMillis() - base;
			}
		}
	}

	/**
	 * Waits at most <code>millis</code> milliseconds plus <code>nanos</code>
	 * nanoseconds for this thread to die.
	 * 
	 * @param millis
	 *            the time to wait in milliseconds.
	 * @param nanos
	 *            0-999999 additional nanoseconds to wait.
	 * @exception IllegalArgumentException
	 *                if the value of millis is negative the value of nanos is
	 *                not in the range 0-999999.
	 * @exception InterruptedException
	 *                if any thread has interrupted the current thread. The
	 *                <i>interrupted status</i> of the current thread is cleared
	 *                when this exception is thrown.
	 */
	public final synchronized void join(long millis, int nanos)
			throws InterruptedException {

		if (millis < 0) {
			throw new IllegalArgumentException("timeout value is negative");
		}

		if (nanos < 0 || nanos > 999999) {
			throw new IllegalArgumentException(
					"nanosecond timeout value out of range");
		}

		if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
			millis++;
		}

		join(millis);
	}

	/**
	 * Waits for this thread to die.
	 * 
	 * @exception InterruptedException
	 *                if any thread has interrupted the current thread. The
	 *                <i>interrupted status</i> of the current thread is cleared
	 *                when this exception is thrown.
	 */
	public final void join() throws InterruptedException {
		join(0);
	}

	/**
	 * Prints a stack trace of the current thread to the standard error stream.
	 * This method is used only for debugging.
	 * 
	 * @see Throwable#printStackTrace()
	 */
	public static void dumpStack() {
		new Exception("Stack trace").printStackTrace();
	}

	/**
	 * Marks this thread as either a daemon thread or a user thread. The Java
	 * Virtual Machine exits when the only threads running are all daemon
	 * threads.
	 * <p>
	 * This method must be called before the thread is started.
	 * <p>
	 * This method first calls the <code>checkAccess</code> method of this
	 * thread with no arguments. This may result in throwing a
	 * <code>SecurityException </code>(in the current thread).
	 * 
	 * @param on
	 *            if <code>true</code>, marks this thread as a daemon thread.
	 * @exception IllegalThreadStateException
	 *                if this thread is active.
	 * @exception SecurityException
	 *                if the current thread cannot modify this thread.
	 * @see #isDaemon()
	 * @see #checkAccess
	 */
	public final void setDaemon(boolean on) {
		checkAccess();
		if (isAlive()) {
			throw new IllegalThreadStateException();
		}
		daemon = on;
	}

	/**
	 * Tests if this thread is a daemon thread.
	 * 
	 * @return <code>true</code> if this thread is a daemon thread;
	 *         <code>false</code> otherwise.
	 * @see #setDaemon(boolean)
	 */
	public final boolean isDaemon() {
		return daemon;
	}

	/**
	 * Determines if the currently running thread has permission to modify this
	 * thread.
	 * <p>
	 * If there is a security manager, its <code>checkAccess</code> method is
	 * called with this thread as its argument. This may result in throwing a
	 * <code>SecurityException</code>.
	 * 
	 * @exception SecurityException
	 *                if the current thread is not allowed to access this
	 *                thread.
	 * @see SecurityManager#checkAccess(Thread)
	 */
	public final void checkAccess() {
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			security.checkAccess(this);
		}
	}

	public String toString() {
		ThreadGroup group = getThreadGroup();
		if (group != null) {
			return "Thread[" + getName() + "," + getPriority() + ","
					+ group.getName() + "]";
		} else {
			return "Thread[" + getName() + "," + getPriority() + "," + "" + "]";
		}
	}

	/**
	 * Returns 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.
	 * 
	 * <p>
	 * 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 <code>checkPermission</code>
	 * method is called with a <code>RuntimePermission("getClassLoader")</code>
	 * permission to see if it's ok to get the context ClassLoader..
	 * 
	 * @return the context ClassLoader for this Thread
	 * 
	 * @throws SecurityException
	 *             if a security manager exists and its
	 *             <code>checkPermission</code> method doesn't allow getting the
	 *             context ClassLoader.
	 * @see #setContextClassLoader
	 * @see SecurityManager#checkPermission
	 * @see RuntimePermission
	 * 
	 * @since 1.2
	 */
	public ClassLoader getContextClassLoader() {
		if (contextClassLoader == null)
			return null;
		SecurityManager sm = System.getSecurityManager();
		if (sm != null) {
			ClassLoader ccl = ClassLoader.getCallerClassLoader();
			if (ccl != null && ccl != contextClassLoader
					&& !contextClassLoader.isAncestor(ccl)) {
				sm
						.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
			}
		}
		return contextClassLoader;
	}

	public void setContextClassLoader(ClassLoader cl) {
		SecurityManager sm = System.getSecurityManager();
		if (sm != null) {
			sm.checkPermission(new RuntimePermission("setContextClassLoader"));
		}
		contextClassLoader = cl;
	}

	/**
	 * Returns <tt>true</tt> if and only if the current thread holds the monitor
	 * lock on the specified object.
	 * 
	 * <p>
	 * This method is designed to allow a program to assert that the current
	 * thread already holds a specified lock:
	 * 
	 * <pre>
	 *     assert Thread.holdsLock(obj);
	 * </pre>
	 * 
	 * @param obj
	 *            the object on which to test lock ownership
	 * @throws NullPointerException
	 *             if obj is <tt>null</tt>
	 * @return <tt>true</tt> if the current thread holds the monitor lock on the
	 *         specified object.
	 * @since 1.4
	 */
	public static native boolean holdsLock(Object obj);

	private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];

	public StackTraceElement[] getStackTrace() {
		if (this != Thread.currentThread()) {
			// check for getStackTrace permission
			SecurityManager security = System.getSecurityManager();
			if (security != null) {
				security
						.checkPermission(SecurityConstants.GET_STACK_TRACE_PERMISSION);
			}
			if (!isAlive()) {
				return EMPTY_STACK_TRACE;
			}
			return dumpThreads(new Thread[] { this })[0];
		} else {
			// Don't need JVM help for current thread
			return (new Exception()).getStackTrace();
		}
	}

	public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
		// check for getStackTrace permission
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			security
					.checkPermission(SecurityConstants.GET_STACK_TRACE_PERMISSION);
			security
					.checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
		}

		// Get a snapshot of the list of all threads
		Thread[] threads = getThreads();
		StackTraceElement[][] traces = dumpThreads(threads);
		Map<Thread, StackTraceElement[]> m = new HashMap<Thread, StackTraceElement[]>(
				threads.length);
		for (int i = 0; i < threads.length; i++) {
			if (threads[i].isAlive()) {
				StackTraceElement[] stackTrace = traces[i];
				if (stackTrace == null) {
					stackTrace = EMPTY_STACK_TRACE;
				}
				m.put(threads[i], stackTrace);
			}
		}
		return m;
	}

	private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = new RuntimePermission(
			"enableContextClassLoaderOverride");

	/** cache of subclass security audit results */
	private static final SoftCache subclassAudits = new SoftCache(10);

	/**
	 * Verifies that this (possibly subclass) instance can be constructed
	 * without violating security constraints: the subclass must not override
	 * security-sensitive non-final methods, or else the
	 * "enableContextClassLoaderOverride" RuntimePermission is checked.
	 */
	private static boolean isCCLOverridden(Class cl) {
		if (cl == Thread.class)
			return false;
		Boolean result = null;
		synchronized (subclassAudits) {
			result = (Boolean) subclassAudits.get(cl);
			if (result == null) {
				/*
				 * Note: only new Boolean instances (i.e., not Boolean.TRUE or
				 * Boolean.FALSE) must be used as cache values, otherwise cache
				 * entry will pin associated class.
				 */
				result = new Boolean(auditSubclass(cl));
				subclassAudits.put(cl, result);
			}
		}
		return result.booleanValue();
	}

	/**
	 * Performs reflective checks on given subclass to verify that it doesn't
	 * override security-sensitive non-final methods. Returns true if the
	 * subclass overrides any of the methods, false otherwise.
	 */
	private static boolean auditSubclass(final Class subcl) {
		Boolean result = (Boolean) AccessController
				.doPrivileged(new PrivilegedAction() {
					public Object run() {
						for (Class cl = subcl; cl != Thread.class; cl = cl
								.getSuperclass()) {
							try {
								cl.getDeclaredMethod("getContextClassLoader",
										new Class[0]);
								return Boolean.TRUE;
							} catch (NoSuchMethodException ex) {
							}
							try {
								Class[] params = { ClassLoader.class };
								cl.getDeclaredMethod("setContextClassLoader",
										params);
								return Boolean.TRUE;
							} catch (NoSuchMethodException ex) {
							}
						}
						return Boolean.FALSE;
					}
				});
		return result.booleanValue();
	}

	private native static StackTraceElement[][] dumpThreads(Thread[] threads);

	private native static Thread[] getThreads();

	public long getId() {
		return tid;
	}

	public enum State {
		NEW, RUNNABLE, WAITING, TIMED_WAITING, TERMINATED;
	}

	public State getState() {
		return sun.misc.VM.toThreadState(threadStatus);
	}

	// Added in JSR-166

	/**
	 * Interface for handlers invoked when a <tt>Thread</tt> abruptly terminates
	 * due to an uncaught exception.
	 * <p>
	 * When a thread is about to terminate due to an uncaught exception the Java
	 * Virtual Machine will query the thread for its
	 * <tt>UncaughtExceptionHandler</tt> using
	 * {@link #getUncaughtExceptionHandler} and will invoke the handler's
	 * <tt>uncaughtException</tt> method, passing the thread and the exception
	 * as arguments. If a thread has not had its
	 * <tt>UncaughtExceptionHandler</tt> explicitly set, then its
	 * <tt>ThreadGroup</tt> object acts as its <tt>UncaughtExceptionHandler</tt>
	 * . If the <tt>ThreadGroup</tt> object has no special requirements for
	 * dealing with the exception, it can forward the invocation to the
	 * {@linkplain #getDefaultUncaughtExceptionHandler default uncaught
	 * exception handler}.
	 * 
	 * @see #setDefaultUncaughtExceptionHandler
	 * @see #setUncaughtExceptionHandler
	 * @see ThreadGroup#uncaughtException
	 * @since 1.5
	 */
	public interface UncaughtExceptionHandler {
		/**
		 * Method invoked when the given thread terminates due to the given
		 * uncaught exception.
		 * <p>
		 * Any exception thrown by this method will be ignored by the Java
		 * Virtual Machine.
		 * 
		 * @param t
		 *            the thread
		 * @param e
		 *            the exception
		 */
		void uncaughtException(Thread t, Throwable e);
	}

	// null unless explicitly set
	private volatile UncaughtExceptionHandler uncaughtExceptionHandler;

	// null unless explicitly set
	private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;

	/**
	 * Set the default handler invoked when a thread abruptly terminates due to
	 * an uncaught exception, and no other handler has been defined for that
	 * thread.
	 * 
	 * <p>
	 * Uncaught exception handling is controlled first by the thread, then by
	 * the thread's {@link ThreadGroup} object and finally by the default
	 * uncaught exception handler. If the thread does not have an explicit
	 * uncaught exception handler set, and the thread's thread group (including
	 * parent thread groups) does not specialize its <tt>uncaughtException</tt>
	 * method, then the default handler's <tt>uncaughtException</tt> method will
	 * be invoked.
	 * <p>
	 * By setting the default uncaught exception handler, an application can
	 * change the way in which uncaught exceptions are handled (such as logging
	 * to a specific device, or file) for those threads that would already
	 * accept whatever &quot;default&quot; behavior the system provided.
	 * 
	 * <p>
	 * Note that the default uncaught exception handler should not usually defer
	 * to the thread's <tt>ThreadGroup</tt> object, as that could cause infinite
	 * recursion.
	 * 
	 * @param eh
	 *            the object to use as the default uncaught exception handler.
	 *            If <tt>null</tt> then there is no default handler.
	 * 
	 * @throws SecurityException
	 *             if a security manager is present and it denies <tt>
	 *             {@link RuntimePermission}
	 *             (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
	 * 
	 * @see #setUncaughtExceptionHandler
	 * @see #getUncaughtExceptionHandler
	 * @see ThreadGroup#uncaughtException
	 * @since 1.5
	 */
	public static void setDefaultUncaughtExceptionHandler(
			UncaughtExceptionHandler eh) {
		SecurityManager sm = System.getSecurityManager();
		if (sm != null) {
			sm.checkPermission(new RuntimePermission(
					"setDefaultUncaughtExceptionHandler"));
		}

		defaultUncaughtExceptionHandler = eh;
	}

	/**
	 * Returns the default handler invoked when a thread abruptly terminates due
	 * to an uncaught exception. If the returned value is <tt>null</tt>, there
	 * is no default.
	 * 
	 * @since 1.5
	 * @see #setDefaultUncaughtExceptionHandler
	 */
	public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
		return defaultUncaughtExceptionHandler;
	}

	/**
	 * Returns the handler invoked when this thread abruptly terminates due to
	 * an uncaught exception. If this thread has not had an uncaught exception
	 * handler explicitly set then this thread's <tt>ThreadGroup</tt> object is
	 * returned, unless this thread has terminated, in which case <tt>null</tt>
	 * is returned.
	 * 
	 * @since 1.5
	 */
	public UncaughtExceptionHandler getUncaughtExceptionHandler() {
		return uncaughtExceptionHandler != null ? uncaughtExceptionHandler
				: group;
	}

	/**
	 * Set the handler invoked when this thread abruptly terminates due to an
	 * uncaught exception.
	 * <p>
	 * A thread can take full control of how it responds to uncaught exceptions
	 * by having its uncaught exception handler explicitly set. If no such
	 * handler is set then the thread's <tt>ThreadGroup</tt> object acts as its
	 * handler.
	 * 
	 * @param eh
	 *            the object to use as this thread's uncaught exception handler.
	 *            If <tt>null</tt> then this thread has no explicit handler.
	 * @throws SecurityException
	 *             if the current thread is not allowed to modify this thread.
	 * @see #setDefaultUncaughtExceptionHandler
	 * @see ThreadGroup#uncaughtException
	 * @since 1.5
	 */
	public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
		checkAccess();
		uncaughtExceptionHandler = eh;
	}

	/**
	 * Dispatch an uncaught exception to the handler. This method is intended to
	 * be called only by the JVM.
	 */
	private void dispatchUncaughtException(Throwable e) {
		getUncaughtExceptionHandler().uncaughtException(this, e);
	}

	/* Some private helper methods */
	private native void setPriority0(int newPriority);

	private native void stop0(Object o);

	private native void suspend0();

	private native void resume0();

	private native void interrupt0();
}

 

 

分享到:
评论
1 楼 2022228 2010-05-13  
废话,浪费资源

相关推荐

    Android开发笔记之:Handler Runnable与Thread的区别详解

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能...

    java并发源码-Concurrency-in-Java-Runnable-and-Thread-Source-code:演示Java并发

    java 并发源码

    Thread、Handler和HandlerThread关系详解

    ,这个题目有点意思,对于很多人来说,可能对Thread和Handler很熟悉,主要涉及到Android的消息机制(Handler、Message、Looper、MessageQueue),详见《 从Handler.post(Runnable r)再一次梳理Android的消息机制(以及...

    2D弹性球动画(对初学者很有参考价值)

    The thread itself is created and started in * the start() method. */ public void run() { while (!pleaseStop) { // Loop until we're asked to stop animate(); // Update and request redraw ...

    ym_java-YOYOPlayer-src

    public class BasicPlayer implements BasicController, Runnable { public static int EXTERNAL_BUFFER_SIZE = 4000 * 4; public static int SKIP_INACCURACY_SIZE = 512; protected Thread m_thread = null; ...

    Thread-Programming-and-Non-blocking-Java-Servers

    线程编程和非阻塞Java服务器 #####何时以及为什么我们将在程序中使用线程? 一个用例是,当您进行长时间运行的操作时,仍然想保持主线程空闲以进行UI ... new Thread ( new (class implements Runnable / Callable )) .

    后端JAVA虚拟机JVM调优必备工具

    IBM Thread and Monitor Dump Analyzer for Java专业JVM调优工具 一、使用方法 1.使用java -jar启动程序 2.找到需要分析的jvm进程 3.使用jstack [pid] &gt; /tmp/sdapjvmlog.txt导出进程的详细日志 4.使用程序打开...

    基于JAVA的网络聊天室(BS)

    * and open the template in the editor. */ package client; /** * * @author Administrator */ import java.awt.*; import java.io.*; import java.net.*; import java.applet.*; import java.util....

    Android代码-teaspoon

    It makes more clear and easy to execute your method on ui thread or background thread. Usage You've seen this code at least once. void someUiLogicInActivity() { this.runOnUiThread(new Runnable() { @...

    Android定时器实现定时执行、重复执行、定时重复执行、定次数执行的多种方式

    1、 Thread(new Runnable) 2、Thread() 3、Timer 4、Handler ····· 代码如下: 1、布局 &lt;?xml version=1.0 encoding=utf-8?&gt; &lt;LinearLayout xmlns:android=...

    android AsynTask处理返回数据和AsynTask使用get,post请求

    开启新的线程可以new Thread() 或实现Runnable接口 什么要使用AsyncTask呢? 如果是使用Thread的run()方法,run()结束之后没有返回值。所以必须要自己建立通信机制 AsyncTask将所有的线程通信都封装成回调函数,...

    testActiveMQ.rar

    * See the License for the specific language governing permissions and * limitations under the License. */ // START SNIPPET: demo /*extern "C" {*/ #include #include &lt;decaf/lang/Thread.h&gt; #include ...

    redar:Java Swift Knife 项目.. - 线程、Quartz、Spring、Spring Integration、Apache Mina、Python

    多线程示例####1.1 ThreadLocals + ThreadPools 该模块通过确保在 Runnable 执行结束时删除 ThreadLocal 上下文来测试内存泄漏保护####1.2。 分叉和加入本模块用于测试 Fork And Join ####1.3。 通过 RMI 使用信号...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第一阶段07讲、策略模式在Thread和Runnable中的应用分析.mp4 │ 高并发编程第一阶段08讲、构造Thread对象你也许不知道的几件事.mp4 │ 高并发编程第一阶段09讲、多线程与JVM内存结构的关系,虚拟机...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段07讲、策略模式在Thread和Runnable中的应用分析.mp4 │ 高并发编程第一阶段08讲、构造Thread对象你也许不知道的几件事.mp4 │ 高并发编程第一阶段09讲、多线程与JVM内存结构的关系,虚拟机...

    Java测试题2答案

    下列说法正确的是 BC A java.lang.Clonable是类 B java.lang.Runnable是接口 C Double对象在java.lang包中 D Double a=1.0是正确的java语句 9.指出正确的表达式AB &lt;br&gt;B Double a=new Double(1.0)...

    幻灯片java手动播放

    public class SR_Slider extends Frame implements ActionListener, WindowListener, Runnable { public static void main(String Pagli[]) { new SR_Slider(); } Thread time; //new thread File fl; URL ...

    超级有影响力霸气的Java面试题大全文档

    sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程...

    【面试】可以在子线程直接new一个Handler吗?怎么做?

    可以在子线程直接new一个Handler,不过需要在子线程里先调用Looper.prepare(),new一个... new Thread(new Runnable() { @Override public void run() { Looper.prepare(); new Handler(){ @Override public void

    android异步消息机制 源码层面彻底解析(1)

    Handler、Message、Loopler、MessageQueen 首先看一下我们平常使用Handler的一个最常见用法。 Handler handler =new ... new Thread(new Runnable() { @Override public void run() { Message message = Messag

Global site tag (gtag.js) - Google Analytics