kvm线程-007-线程状态-THREAD_SUSPENDED,THREAD_DEAD

本文介绍线程状态THREAD_SUSPENDED,THREAD_DEAD的使用。

THREAD_SUSPENDE

该状态设置的地方为:

  1. startThread,该方法在kvm线程-006-线程状态-THREAD_ACTIVE 中有介绍
  2. suspendThread,该方法的代码如下:
void suspendThread(void)
{
  // 1. 如果CurrentThread 为null,则直接return
  if (CurrentThread == NULL) {
     
      return;
  }

  // 2.
  if (!(CurrentThread->state & THREAD_SUSPENDED)) {
      /*  2. 保存线程的fp,sp,ip  */
      storeExecutionEnvironment(CurrentThread);

      /*  宏展开为Timeslice = 0,也就是立即进行线程切换*/
      signalTimeToReschedule();
  }
  /*  3. 设置状态为THREAD_SUSPENDED */
  CurrentThread->state |= THREAD_SUSPENDED;
  /*  将CurrentThread设为null */
  CurrentThread = NIL;

}

该方法的调用点有:

  1. Java_java_lang_Thread_sleep,此方法在kvm 本地方法实现有介绍
  2. monitorWait,后文介绍
  3. monitorEnter,后文介绍
  4. asyncFunctionProlog,异步,此处不介绍
  5. stopThread,后文介绍
  6. Java_com_sun_cldc_io_Waiter_waitForIO 此处不介绍

THREAD_DEAD

当是一个线程run方法结束的时候,会调用stopThread()方法.代码如下:

SELECT6(IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN)
        /* Return from method */
        BYTE*  previousIp    = fp->previousIp;
        OBJECT synchronized  = fp->syncObject;

        TRACE_METHOD_EXIT(fp->thisMethod);

        if (synchronized != NULL) {
            char*  exitError;
            if (monitorExit(synchronized, &exitError) == MonitorStatusError) {
                exception = exitError;
                goto handleException;
            }
        }

        /* Special case where we are killing a thread */
        if (previousIp == KILLTHREAD) { 
            VMSAVE
            stopThread();// 此处终止线程
            VMRESTORE
            if (areAliveThreads()) {
                goto reschedulePoint;
            } else {
                return;                   // 此时意味着所有线程都执行完毕了.
            }
        }
        
        // 省略其他代码

关于previousIp == KILLTHREAD,当我们创建线程的时候,有如下代码(在kvm线程-006-线程状态-THREAD_ACTIVE 中有介绍):

// 设置栈帧
setSP((thisThread->stack->cells - 1) + thisMethod->argCount);
setFP(NULL);
setIP(KILLTHREAD);
pushFrame(thisMethod);

因此当previousIp == KILLTHREAD时,就意味着该线程最后一个栈帧执行结束了,应该终止了.stopThread的方法如下:

void stopThread(void)
{
    THREAD thisThread = CurrentThread;

#if INCLUDEDEBUGCODE
    if (tracethreading) {
        TraceThread(thisThread, "Stopping");
    }
#endif

    /*  1.将线程暂停*/
    suspendThread();

    /* Always force the end of the current thread */
    CurrentThread = NIL;

    /* Make the thread be no longer alive 2. 修改线程的状态 */
    thisThread->state = THREAD_DEAD;
    AliveThreadCount--;

    /*  3. 通知其他线程,如果该线程有监视对象的话 */
    if (OBJECT_MHC_TAG(thisThread->javaThread) == MHC_MONITOR) {
        removeCondvarWait(OBJECT_MHC_MONITOR(thisThread->javaThread), TRUE);
    }

    /*  4. 释放线程的资源*/
    DismantleThread(thisThread);
}

DismantleThread代码如下:

void
DismantleThread(THREAD thisThread)
{
    START_TEMPORARY_ROOTS
        IS_TEMPORARY_ROOT(thisThread, thisThread);

#if ENABLE_JAVA_DEBUGGER
        if (vmDebugReady) {
            CEModPtr cep;
            storeExecutionEnvironment(thisThread);
            cep = GetCEModifier();
            cep->threadID = getObjectID((OBJECT)thisThread->javaThread);
            setEvent_ThreadDeath(cep);
            FreeCEModifier(cep);
        }
#endif /* ENABLE_JAVA_DEBUGGER */

    /*
     * 1. 设置线程状态为:THREAD_DEAD
     */
    thisThread->state = THREAD_DEAD;
    // 2. 将当前线程从AllThreads中删除
    if (AllThreads == thisThread) {// 此时的情况是队列头为thisThread
        AllThreads = AllThreads->nextAliveThread;
    } else {
        THREAD prevThread = AllThreads;
        while (prevThread->nextAliveThread != thisThread) {
            prevThread = prevThread->nextAliveThread;
        }
        prevThread->nextAliveThread = thisThread->nextAliveThread;
    }
    thisThread->nextAliveThread = NULL;
    thisThread->stack = NULL;
    thisThread->fpStore = NULL;
    thisThread->spStore = NULL;
    // 3.如果当前线程在timer queue中,就删除
    if (inTimerQueue(thisThread)) {
        removePendingAlarm(thisThread);
    }
    END_TEMPORARY_ROOTS
}

你可能感兴趣的:(kvm)