27 September 2013


package test.java.lang.thread;

public class TestThread {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread();



Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:682)
at test.java.lang.thread.TestThread.main(TestThread.java:8)


if (threadStatus != 0)
        throw new IllegalThreadStateException();


private volatile int threadStatus = 0;


JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
    JavaThread *native_thread = NULL;

    // We cannot hold the Threads_lock when we throw an exception,
    // due to rank ordering issues. Example:  we might need to grab the
    // Heap_lock while we construct the exception.
    bool throw_illegal_thread_state = false;

    // We must release the Threads_lock before we can post a jvmti event
    // in Thread::start.
        // Ensure that the C++ Thread and OSThread structures aren't freed before
        // we operate.
        MutexLocker mu(Threads_lock);

        // Since JDK 5 the java.lang.Thread threadStatus is used to prevent
        // re-starting an already started thread, so we should usually find
        // that the JavaThread is null. However for a JNI attached thread
        // there is a small window between the Thread object being created
        // (with its JavaThread set) and the update to its threadStatus, so we
        // have to check for this
        if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {
            throw_illegal_thread_state = true;
        } else {
            // We could also check the stillborn flag to see if this thread was already stopped, but
            // for historical reasons we let the thread detect that itself when it starts running

            jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
            // Allocate the C++ Thread structure and create the native thread.  The
            // stack size retrieved from java is signed, but the constructor takes
            // size_t (an unsigned type), so avoid passing negative values which would
            // result in really large stacks.
            size_t sz = size > 0 ? (size_t) size : 0;
            native_thread = new JavaThread(&thread_entry, sz);

            // At this point it may be possible that no osthread was created for the
            // JavaThread due to lack of memory. Check for this situation and throw
            // an exception if necessary. Eventually we may want to change this so
            // that we only grab the lock if the thread was created successfully -
            // then we can also do this check and throw the exception in the
            // JavaThread constructor.
            if (native_thread->osthread() != NULL) {
                // Note: the current thread is not being used within "prepare".

    if (throw_illegal_thread_state) {

    assert(native_thread != NULL, "Starting null thread?");

    if (native_thread->osthread() == NULL) {
        // No one should hold a reference to the 'native_thread'.
        delete native_thread;
        if (JvmtiExport::should_post_resource_exhausted()) {
                "unable to create new native thread");
            "unable to create new native thread");




其中Thread::start(Thread* thread)方法的实现如下,

void Thread::start(Thread* thread) {
    trace("start", thread);
    // Start is different from resume in that its safety is guaranteed by context or
    // being called from a Java method synchronized on the Thread object.
    if (!DisableStartThread) {
        if (thread->is_Java_thread()) {
            // Initialize the thread state to RUNNABLE before starting this thread.
            // Can not set it after the thread started because we do not know the
            // exact thread state at that time. It could be in MONITOR_WAIT or
            // in SLEEPING or some other state.