目录
Java中操作线程都是通过Thread的API来实现,其中核心逻辑都封装在本地方法中,其实现在jdk\src\share\native\java\lang\Thread.c中,部分方法如将当前线程置为悬浮状态的suspend,从悬浮状态恢复正常执行的resume方法和停止线程执行的stop方法都被标记成过时方法,本篇博客就不关注了,重点探讨其他的常用方法的实现细节。
1、start
start方法用于创建一个关联的本地线程并启动该线程的执行,其实现如下:
public synchronized void start() {
//0表示状态是NEW,如果不是0则抛出异常
if (threadStatus != 0)
throw new IllegalThreadStateException();
//通知所属的ThreadGroup该线程启动执行了,ThreadGroup本身维护了已启动线程的数组和计数
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
//增加未启动线程计数,将其从已启动数组中移除
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
//启动失败本身会抛出异常给调用方
}
}
}
void add(Thread t) {
synchronized (this) {
if (destroyed) {
throw new IllegalThreadStateException();
}
//threads是一个数组,维护所有已启动的线程
if (threads == null) {
threads = new Thread[4];
} else if (nthreads == threads.length) {
//如果threads满了,则扩容一倍
threads = Arrays.copyOf(threads, nthreads * 2);
}
//保存t
threads[nthreads] = t;
//已启动线程数加1
nthreads++;
//未启动线程数减1,执行Thread的构造方法时会将该计数加1
nUnstartedThreads--;
}
}
void threadStartFailed(Thread t) {
synchronized(this) {
//从threads数组中移除
remove(t);
//未启动线程数加1
nUnstartedThreads++;
}
}
private void remove(Thread t) {
synchronized (this) {
if (destroyed) {
return;
}
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
//将i以后的数组元素整体往前挪一位
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
//nthreads对应的数组元素置为NULL
threads[nthreads] = null;
break;
}
}
}
}
start0就是一个本地方法,会给当前Thread实例创建一个C++ JavaThread实例和OSThread实例,前者是线程在JVM中的表示,后者表示底层操作系统的原生线程,这三个都是一对一关系,Thread实例和JavaThread,JavaThread和OSThread都保存了彼此的引用。创建并初始化完成后,会设置OSThread的优先级,栈帧大小等属性,然后启动OSThread执行JavaThread的run方法,该方法会执行Thread实例的run方法。注意如果重复调用start方法或者因为内存不足导致OSThread创建失败都会抛出异常,其实现如下:
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) {
//如果关联的JavaThread不为空,说明该线程已经启动过,需要抛出异常
throw_illegal_thread_state = true;
} else {
//获取stackSize属性,1.4以上不是从Thread实例中读取,直接返回0
jlong size =
java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
size_t sz = size > 0 ? (size_t) size : 0;
//创建JavaThread和关联的OSThread
native_thread = new JavaThread(&thread_entry, sz);
if (native_thread->osthread() != NULL) {
//osthread不为空,prepare方法会建立Java Thread实例同JavaThread之间的关联关系
//并将Java线程的优先级映射成原生线程的优先级并设置
native_thread->prepare(jthread);
}
}
}
if (throw_illegal_thread_state) {
//关联的JavaThread不为空,抛出异常
THROW(vmSymbols::java_lang_IllegalThreadStateException());
}
assert(native_thread != NULL, "Starting null thread?");
if (native_thread->osthread() == NULL) {
//创建osthread失败,抛出异常
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");
}
//启动线程开始执行
Thread::start(native_thread);
JVM_END
//获取eetop属性,该属性是一个long类型,保存关联的JavaThread指针
JavaThread* java_lang_Thread::thread(oop java_thread) {
return (JavaThread*)java_thread->address_field(_eetop_offset);
}
jlong java_lang_Thread::stackSize(oop java_thread) {
//获取stackSize属性
if (_stackSize_offset > 0) {
//只有1.4才会读取
assert(JDK_Version::is_gte_jdk14x_version(), "sanity check");
return java_thread->long_field(_stackSize_offset);
} else {
return 0;
}
}
static void thread_entry(JavaThread* thread, TRAPS) {
HandleMark hm(THREAD);
Handle obj(THREAD, thread->threadObj());
JavaValue result(T_VOID);
//调用Thread的run方法
JavaCalls::call_virtual(&result,
obj,
KlassHandle(THREAD, SystemDictionary::Thread_klass()),
vmSymbols::run_method_name(),
vmSymbols::void_method_signature(),
THREAD);
}
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
Thread() //Thread的构造方法就是初始化Thread的各属性
{
if (TraceThreadEvents) {
tty->print_cr("creating thread %p", this);
}
//初始化JavaThread自有的各种属性
initialize();
_jni_attach_state = _not_attaching_via_jni;
//entry_point就是执行的run方法
set_entry_point(entry_point);
os::ThreadType thr_type = os::java_thread;
//是否编译线程,编译线程也是JavaThread,但是对应的os::ThreadType类型不同
thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
os::java_thread;
//创建一个原生线程,底层通过pthread_create创建,创建成功后将其设置到Thread的_osthread属性中,然后等待其初始化完成
//,初始化结束后在startThread_lock上等待被唤醒
//如果内存不足导致创建失败,则该属性为NULL
os::create_thread(this, thr_type, stack_sz);
}
//prio默认是NoPriority
void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
Handle thread_oop(Thread::current(),
JNIHandles::resolve_non_null(jni_thread));
assert(InstanceKlass::cast(thread_oop->klass())->is_linked(),
"must be initialized");
//保存关联的Java Th