Android中线程Thread源码解析
一、Thread的介绍
Thread线程是进程中的独立运行的子任务。线程是CPU调度的最基本的单元,线程资源开销相对于进程而言比较小,所以我们一般是创建线程来执行任务。
1、Thread继承关系
Thread类实现了Runnable接口,且Thread类含有多个构造器进行重载
2、Thread线程状态
Thread线程主要有6种状态分别为:NEW(线程创建状态)、RUNNABLE(可运行状态)、BLOCKED(阻塞状态)、WAITING(等待状态)、TIMED_WAITING(计时等待状态)、TERMINATED(终止状态)
public enum State {
NEW, //新创建,还未启动
RUNNABLE,//可运行状态
BLOCKED,//阻塞状态,等待同步锁的释放,如果获得锁就会自动进入运行状态
WAITING,//等待状态, 需要被其他线程唤醒(notify,notifyAll的方法调用)
TIMED_WAITING,//计时等待状态
TERMINATED//被终止状态
}
Thread线程状态转化图:
3、线程名的设置
线程名的设置一般有两种方式,第一种就是通过Thread类构造器指定name参数,另一种就是通过setName方法指定;默认情况下是通过”Thread-“ + nextThreadNum()来指定
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
thread1.setName("WorkerThread-1");//通过setName方法修改线程名,也可在构造器参数指定,默认是"Thread-" + nextThreadNum()
thread1.start();
System.out.println(Thread.currentThread().getName());//getName方法获取线程名
}
setName修改线程名源码分析:
public final synchronized void setName(String name) {
checkAccess();//检查访问权限
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
if (threadStatus != 0) {
setNativeName(name);//调用Native层方法设置线程名setNativeName
}
}
private native void setNativeName(String name);
setNativeName映射对应JNI层的Thread.c
文件
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
{"suspend0", "()V", (void *)&JVM_SuspendThread},
{"resume0", "()V", (void *)&JVM_ResumeThread},
{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},
{"yield", "()V", (void *)&JVM_Yield},
{"sleep", "(J)V", (void *)&JVM_Sleep},
{"currentThread", "()" THD, (void *)&JVM_CurrentThread},
{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},
{"interrupt0", "()V", (void *)&JVM_Interrupt},
{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},
{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},//setNativeName
};
然后继续转到jvm.cpp中的JVM_SetNativeThreadName
方法
JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))
JVMWrapper("JVM_SetNativeThreadName");
ResourceMark rm(THREAD);
oop java_thread = JNIHandles::resolve_non_null(jthread);
JavaThread* thr = java_lang_Thread::thread(java_thread);
if (Thread::current() == thr && !thr->has_attached_via_jni()) {
const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
//最后调用os中的set_native_thread_name方法
os::set_native_thread_name(thread_name);
}
JVM_END
最后,进入os中的set_native_thread_name
方法
void os::set_native_thread_name(const char *name) {
#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
if (name != NULL) {
char buf[MAXTHREADNAMESIZE];
snprintf(buf, sizeof(buf), "Java: %s", name);
//调用POSIX线程标准库pthread库中的setname_np
pthread_setname_np(buf);
}
#endif
}
4、守护线程
守护线程顾名思义就是为其他线程服务的,比如JVM中的垃圾回收线程就是守护线程。
守护线程的特点:
1、当守护的用户线程执行完毕了,JVM虚拟机退出,那么这个守护线程也就停止了。
2、守护线程作为一个服务线程,如果服务的线程对象不存在了,那么这个守护线程也就没有存在的意义了。
守护线程的规则:
1、在线程启动前设置为守护线程,通过
setDaemon(boolean on)
2、不要使用守护线程访问共享资源(数据库、文件等),因为它的生命周期随时都可能结束
3、守护线程中产生的新线程也是守护线程
守护线程的使用:
将一个线程设置成守护线程很简单只需要调用thread.setDaemon(true)
即可
5、线程的优先级
所谓线程优先级高仅仅是表示线程获取CPU时间片的几率高,但是这是不确定的因素
线程的优先级是高度依赖操作系统的,不同平台上都有所区别
/**
* 线程最低优先级 1
*/
public final static int MIN_PRIORITY = 1;
/**
* 线程默认优先级 5
*/
public final static int NORM_PRIORITY = 5;
/**
* 线程最高优先级 10
*/
public final static int MAX_PRIORITY = 10;
可以通过setPriority
方法设置优先级:
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);
}
}
//setPriority0是Native方法
private native void setPriority0(int newPriority);
setPriority0
JNI层方法
//Thread.c
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
{"suspend0", "()V", (void *)&JVM_SuspendThread},
{"resume0", "()V", (void *)&JVM_ResumeThread},
{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},//对应映射到JVM_SetThreadPriority方法
{"yield", "()V", (void *)&JVM_Yield},
{"sleep", "(J)V", (void *)&JVM_Sleep},
{"currentThread", "()" THD, (void *)&JVM_CurrentThread},
{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},
{"interrupt0", "()V", (void *)&JVM_Interrupt},
{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},
{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};
//jvm.cpp
JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))
JVMWrapper("JVM_SetThreadPriority");
// Ensure that the C++ Thread and OSThread structures aren't freed before we operate
MutexLocker ml(Threads_lock);
//通过jthread对象转换成java_thread的oop对象
oop java_thread = JNIHandles::resolve_non_null(jthread);
//通过set_priority方法给java_thread设置优先级
java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);
//再通过thread方法转化成JavaThread
JavaThread* thr = java_lang_Thread::thread(java_thread);
if (thr != NULL) { // Thread not yet started; priority pushed down when it is
Thread::set_priority(thr, (ThreadPriority)prio);//调用Thread中的set_priority方法设置优先级
}
JVM_END
//thread.cpp
void Thread::set_priority(Thread* thread, ThreadPriority priority) {
trace("set priority", thread);
debug_only(check_for_dangling_thread_pointer(thread);)
// Can return an error!
(void)os::set_priority(thread, priority);//最后调用os中的set_priority方法
}
//os_bsd.cpp
OSReturn os::set_native_priority(Thread* thread, int newpri) {
if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
#ifdef __OpenBSD__
// OpenBSD pthread_setprio starves low priority threads
return OS_OK;
#elif defined(__FreeBSD__)
int ret = pthread_setprio(thread->osthread()->pthread_id(), newpri);
#elif defined(__APPLE__) || defined(__NetBSD__)
struct sched_param sp;
int policy;
pthread_t self = pthread_self();
if (pthread_getschedparam(self, &policy, &sp) != 0)
return OS_ERR;
sp.sched_priority = newpri;
if (pthread_setschedparam(self, policy, &sp) != 0)
return OS_ERR;
return OS_OK;
#else
//setpriority设置优先级,分别设置PRIO_PROCESS进程,thread线程Id,优先级newpri
int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
return (ret == 0) ? OS_OK : OS_ERR;
#endif
}
二、Thread的基本使用
在Java中使用Thread线程方式主要有4种方法,分别是:Thread类+匿名类+重写run方法、Thread继承子类+重写run方法、Thread+Runnable匿名类+重写run方法、Thread+Runnable实现子类+重写run方法
1、Thread类+匿名类+重写run
public class Test {
public static void main(String[] args) {
Thread thread = new Thread("Thread#1") {
@Override
public void run() {
//todo sth
}
};
thread.start();
}
}
2、Thread继承子类+重写run
public class Test {
static class UserThread extends Thread {
public UserThread() {
super("Thread#2");
}
@Override
public void run() {
//todo sth
}
}
public static void main(String[] args) {
UserThread thread = new UserThread();
thread.start();
}
}
3、Thread+Runnable匿名接口+重写run
public class Test {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
//todo sth
}
},"Thread#3").start();
}
}
4、Thread+Runnable实现子类+重写run
public class Test {
static class TaskRunnable implements Runnable {
@Override
public void run() {
//todo sth
}
}
public static void main(String[] args) {
new Thread(new TaskRunnable(), "Thread#4").start();
}
}
5、Thread匿名类和Thread继承子类区别
方式 | 优点 | 缺点 | 应用场景 |
---|---|---|---|
Thread继承子类 | 创建的线程类和对象可复用 | 使用复杂,代码量大 | 需要复用线程类和对象 |
Thread匿名类 | 使用简单 | 创建的线程类和对象不可复用 | 不需要复用线程类和对象 |
6、Runnable匿名接口和Runnable实现子类区别
方式 | 优点 | 缺点 | 应用场景 |
---|---|---|---|
Thread+Runnable实现子类 | 功能扩展性好 | 使用复杂,代码量大 | 需要扩展多线程功能 |
Thread+Runnable匿名类 | 使用简单 | 功能扩展性差 | 不需要扩展多线程功能 |
7、继承Thread类与实现Runnable接口对比
三、Thread源码解析
1、Thread的构造器
在Java中线程Thread重载很多个构造器,总共有9个构造器进行重载。重载的参数主要有: name(线程名)、group(线程组)、target(Runnable对象)等
2、init方法分析
通过以上init
源码分析,我们可以得到以下信息:
一个线程的父线程parent, 就是该线程被创建时所处的线程,比如在主线程A中创建了新的线程B,那么B的parent就是线程A
如果创建的新线程的parent是一个守护线程,那么这个新的线程也是守护线程;换句话说在守护线程内创建一个线程也是守护线程
创建的新线程默认优先级为它的parent线程的优先级
创建的新线程和它的parent线程处于同一个线程组
3、start方法具体实现分析
在Java中我们一般都是通过start方法来启动一个已创建的线程,那么start方法到底做了什么呢?
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
//把当前的线程加入到线程组group中
group.add(this);
boolean started = false;
try {
//调用start0 Native方法
start0();
started = true;//将线程启动状态置为true, 已启动
} finally {
try {
if (!started) {//线程启动状态为false
group.threadStartFailed(this);//需要交由它的线程组的threadStartFailed来处理
}
} catch (Throwable ignore) {
}
}
}
//定义的start0 native方法
private native void start0();
线程start调用的时候首先会把当前线程加入它的线程组列表中,然后线程组中未启动线程计数减1
//ThreadGroup中的add方法
//通知group线程组当前这个线程被启动了,以便于可以把它加入到线程组线程列表中,
//此外线程组中的未启动的线程数需要自减1
void add(Thread t) {
synchronized (this) {
if (destroyed) {
throw new IllegalThreadStateException();
}
//threads是一个Thread的动态数组
if (threads == null) {
//默认开始是创建size为4的Thread数组
threads = new Thread[4];
} else if (nthreads == threads.length) {
//之后默认扩容,扩大为当前线程数组长度的2倍
threads = Arrays.copyOf(threads, nthreads * 2);
}
threads[nthreads] = t;//把启动线程的加入线程列表中,实际上加入到一个动态数组中
//启动线程的计数累加1
nthreads++;
//未启动线程的计数累减1
nUnstartedThreads--;
}
}
对于start0线程启动失败的情况,会把它交给它的线程组group中的threadStartFailed
方法来处理
void threadStartFailed(Thread t) {
synchronized(this) {
remove(t);//调用remove方法将启动失败线程从已启动线程列表中移除
nUnstartedThreads++;//然后未启动线程计数累加1
}
}
private void remove(Thread t) {
synchronized (this) {
if (destroyed) {
return;
}
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
threads[nthreads] = null;//回收启动失败线程在已启动线程列表中的位置
break;
}
}
}
}
然后我们进入核心方法start0
Native方法来研究一下
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},//映射对应的方法JVM_StartThread
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
{"suspend0", "()V", (void *)&JVM_SuspendThread},
{"resume0", "()V", (void *)&JVM_ResumeThread},
{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},
{"yield", "()V", (void *)&JVM_Yield},
{"sleep", "(J)V", (void *)&JVM_Sleep},
{"currentThread", "()" THD, (void *)&JVM_CurrentThread},
{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},
{"interrupt0", "()V", (void *)&JVM_Interrupt},
{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},
{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};
继续来看下jvm.cpp
中的JVM_StartThread
方法
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_StartThread");
//JavaThread的C++类定义的*native_thread对象
JavaThread *native_thread = NULL;
bool throw_illegal_thread_state = false;
{
//获取互斥锁
MutexLocker mu(Threads_lock);
//线程状态的检查,确保线程尚未启动
if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {
throw_illegal_thread_state = true;
} else {
//通过stackSize获得堆栈的大小, 来分配C++的Thread对象内存大小
jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
//最后返回size_t无符号类型,所以需要避免负数的传递,size <= 0就直接返回0
size_t sz = size > 0 ? (size_t) size : 0;
//注意: 创建C++层的本地线程JavaThread对象,&thread_entry为Thread中的run方法入口,请参考下面thread_entry函数的介绍
native_thread = new JavaThread(&thread_entry, sz);
//检查本地线程是否包含OSThread, 因为可能出现因为内存不足导致OSThread创建失败
if (native_thread->osthread() != NULL) {
//准备JavaThread,链接Java线程对象到C++线程
native_thread->prepare(jthread);
}
}
}
if (throw_illegal_thread_state) {
THROW(vmSymbols::java_lang_IllegalThreadStateException());
}
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()) {
JvmtiExport::post_resource_exhausted(
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,
"unable to create new native thread");
}
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
"unable to create new native thread");
}
//启动JavaThread本地线程
Thread::start(native_thread);
JVM_END
//&thread_entry是一个C++静态函数,它将作为JavaThread类构造函数的参数传入
static void thread_entry(JavaThread* thread, TRAPS) {
HandleMark hm(THREAD);
Handle obj(THREAD, thread->threadObj());
JavaValue result(T_VOID);
JavaCalls::call_virtual(&result,
obj,
KlassHandle(THREAD, SystemDictionary::Thread_klass()),
vmSymbols::run_method_name(),
vmSymbols::void_method_signature(),
THREAD);
}
Thread.cpp中的JavaThread的构造器
//C++层的JavaThread类
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
Thread()
#if INCLUDE_ALL_GCS
, _satb_mark_queue(&_satb_mark_queue_set),
_dirty_card_queue(&_dirty_card_queue_set)
#endif // INCLUDE_ALL_GCS
{
if (TraceThreadEvents) {
tty->print_cr("creating thread %p", this);
}
//初始化实例变量
initialize();
_jni_attach_state = _not_attaching_via_jni;
//注意: 设置Java执行线程入口,最终会调用, 传进来的entry_point是thread_entry。这种方法会调用Thread.run方法。
set_entry_point(entry_point);
os::ThreadType thr_type = os::java_thread;
thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
os::java_thread;
//通过os::create_thread创建一个OSThread
os::create_thread(this, thr_type, stack_sz);
_safepoint_visible = false;
}
再着进入os::create_thread方法
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
assert(thread->osthread() == NULL, "caller responsible");
// 1、构造OSThread对象
OSThread* osthread = new OSThread(NULL, NULL);
if (osthread == NULL) {
return false;
}
osthread->set_thread_type(thr_type);
//2、将OSThread状态设置ALLOCATED状态
osthread->set_state(ALLOCATED);
//3、将OSThread和JavaThread关联
thread->set_osthread(osthread);
//4、初始化线程属性
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// stack size
...
ThreadState state;
{
pthread_t tid;
//5、使用Posix中的Pthread库中的pthread_create创建本地子线程并且可执行
//本地子线程运行java_start方法,JavaThread对象thread作为参数
//pthread_create方法有四个参数:
// &tid(子程序返回的新线程的唯一标识)、
// &attr(可用于设置线程属性,默认可为NULL)
// java_start(线程创建后将执行传入的方法,java_start就是要执行的方法)
// thread 是给java_start方法传入的参数对象,默认不传为NULL
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
pthread_attr_destroy(&attr);
if (ret != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
return false;
}
// Store pthread info into the OSThread
osthread->set_pthread_id(tid);
// 等待子线程初始化或中止
{
Monitor* sync_with_child = osthread->startThread_lock();
MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
while ((state = osthread->get_state()) == ALLOCATED) {
sync_with_child->wait(Mutex::_no_safepoint_check_flag);
}
}
}
// Aborted due to thread limit being reached
if (state == ZOMBIE) {
thread->set_osthread(NULL);
delete osthread;
return false;
}
assert(state == INITIALIZED, "race condition");
return true;
}
根据上述代码分析可知,会通过Posix库中pthread库中的pthread_create方法创建线程,然而传入第三个参数就是java_start,第四个参数thread就是作为java_start方法的参数,就是创建好线程后会执行该java_start方法,所以我们需要深入java_start方法。
//这里的*thread就是pthread_create方法中传入的第四个参数thread,作为java_start方法的参数
static void *java_start(Thread *thread) {
static int counter = 0;
//拿到进程ID
int pid = os::current_process_id();
alloca(((pid ^ counter++) & 7) * 128);
//把thread对象存储到C++层中的ThreadLocalStorage
ThreadLocalStorage::set_thread(thread);
//创建OSThread对象
OSThread* osthread = thread->osthread();
Monitor* sync = osthread->startThread_lock();
if (!_thread_safety_check(thread)) {
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
osthread->set_state(ZOMBIE);
sync->notify_all();
return NULL;
}
//设置osthread的线程ID
osthread->set_thread_id(os::Bsd::gettid());
#ifdef __APPLE__
uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id());
guarantee(unique_thread_id != 0, "unique thread id was not found");
osthread->set_unique_thread_id(unique_thread_id);
#endif
os::Bsd::hotspot_sigmask(thread);
os::Bsd::init_thread_fpu_state();
#ifdef __APPLE__
if (objc_registerThreadWithCollectorFunction != NULL) {
objc_registerThreadWithCollectorFunction();
}
#endif
// handshaking with parent thread
{
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
// 将OSThread从原来的ALLOCATED状态改变为INITIALIZED状态
osthread->set_state(INITIALIZED);
sync->notify_all();
// 一直等待调用os::start_thread()方法来OSThread状态INITIALIZED改变,这样才会往下执行thread->run()
while (osthread->get_state() == INITIALIZED) {
sync->wait(Mutex::_no_safepoint_check_flag);
}
}
// 调用JavaThread中的run方法
thread->run();
return 0;
}
上述都是JVM_StartThread
方法中的new JavaThread(&thread_entry, sz)
创建JavaThread
对象过程,其中涉及到创建os::create_thread
方法,然后再通过pthread_create
创建真正本地线程,传入java_start
要执行的方法。最后我们回到JVM_StartThread
方法。
JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_StartThread");
JavaThread *native_thread = NULL;
bool throw_illegal_thread_state = false;
{
MutexLocker mu(Threads_lock);
if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {
throw_illegal_thread_state = true;
} else {
jlong size =
java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
size_t sz = size > 0 ? (size_t) size : 0;
native_thread = new JavaThread(&thread_entry, sz);
if (native_thread->osthread() != NULL) {
native_thread->prepare(jthread);
}
}
}
...
Thread::start(native_thread);//最后就是真正的Thread::start的方法
JVM_END
接着一起来看下Thread.cpp
中的Thread::start
方法
void Thread::start(Thread* thread) {
trace("start", thread);
if (!DisableStartThread) {
if (thread->is_Java_thread()) {
//设置线程状态为RUNNABLE
java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(), java_lang_Thread::RUNNABLE);
}
//最后调用os中的start_thread方法
os::start_thread(thread);
}
}
然后一起来看下os.cpp
中的start_thread
方法
void os::start_thread(Thread* thread) {
// guard suspend/resume
MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);
//拿到JavaThread对象中的osThread对象
OSThread* osthread = thread->osthread();
//设置osThread对象为RUNNABLE状态,OSThread状态改变了,所以上述*java_start中的thread->run执行
osthread->set_state(RUNNABLE);
pd_start_thread(thread);
}
osThread状态由INITIALIZED
变为了RUNNABLE
状态后,*java_start
中最后的thread->run()
执行。
//这里的*thread就是pthread_create方法中传入的第四个参数thread,作为java_start方法的参数
static void *java_start(Thread *thread) {
...
// handshaking with parent thread
{
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
// 将OSThread从原来的ALLOCATED状态改变为INITIALIZED状态
osthread->set_state(INITIALIZED);
sync->notify_all();
// 等待调用os::start_thread()方法来OSThread状态改变,这样才会往下执行thread->run()
while (osthread->get_state() == INITIALIZED) {
sync->wait(Mutex::_no_safepoint_check_flag);
}
}
// osThread状态由`INITIALIZED`变为了`RUNNABLE`状态,调用JavaThread中的run方法
thread->run();
return 0;
}
最后一起来看下JavaThread
中的run
方法
// The first routine called by a new Java thread
void JavaThread::run() {
// 初始化操作...
this->initialize_tlab();
...
//最后调用thread_main_inner方法
thread_main_inner();
// Note, thread is no longer valid at this point!
}
接着看下thread_main_inner
方法
void JavaThread::thread_main_inner() {
assert(JavaThread::current() == this, "sanity check");
assert(this->threadObj() != NULL, "just checking");
//如果没有pending异常的话就会执行Thread entry point,
if (!this->has_pending_exception() &&
!java_lang_Thread::is_stillborn(this->threadObj())) {
{
ResourceMark rm(this);
this->set_native_thread_name(this->get_thread_name());
}
HandleMark hm(this);
//注意点: 还记得传入entry_point吗?一开始传入的是thread_entry, 也就是对应java.lang.Thread中的run,这样我们run就得以执行
this->entry_point()(this, this);
}
DTRACE_THREAD_PROBE(stop, this);
//执行清理工作
this->exit(false);
//销毁释放JavaThread对象
delete this;
}
最后,我们知道entry_point
实际上就是调用了jvm.cpp
中的thread_entry
方法
static void thread_entry(JavaThread* thread, TRAPS) {
HandleMark hm(THREAD);
Handle obj(THREAD, thread->threadObj());
JavaValue result(T_VOID);
//注意这里实际上就是在调用java.lang.thread中的run方法,其中vmSymbols::run_method_name()对应的就是方法名"run"
JavaCalls::call_virtual(&result,
obj,
KlassHandle(THREAD, SystemDictionary::Thread_klass()),
vmSymbols::run_method_name(),
vmSymbols::void_method_signature(),
THREAD);
}
//vmSysbols.hpp
template(daemon_name, "daemon")
template(eetop_name, "eetop")
template(thread_status_name, "threadStatus")
template(run_method_name, "run") //run方法
template(exit_method_name, "exit")
template(add_method_name, "add")
template(remove_method_name, "remove")
template(parent_name, "parent")