本文介绍线程状态THREAD_SUSPENDED,THREAD_DEAD的使用。
THREAD_SUSPENDE
该状态设置的地方为:
- startThread,该方法在kvm线程-006-线程状态-THREAD_ACTIVE 中有介绍
- 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;
}
该方法的调用点有:
- Java_java_lang_Thread_sleep,此方法在kvm 本地方法实现有介绍
- monitorWait,后文介绍
- monitorEnter,后文介绍
- asyncFunctionProlog,异步,此处不介绍
- stopThread,后文介绍
- 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
}