目录
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 Thread实例
set_threadObj(thread_oop());
//设置Java Thread实例的eetop属性,保存当前JavaThread指针
java_lang_Thread::set_thread(thread_oop(), this);
if (prio == NoPriority) {
//获取priority属性
prio = java_lang_Thread::priority(thread_oop());
assert(prio != NoPriority, "A valid priority should be present");
}
//将Java线程优先级映射成原生线程优先级,然后设置原生线程的优先级
Thread::set_priority(this, prio);
prepare_ext();
// Add the new thread to the Threads list and set it in motion.
// We must have threads lock in order to call Threads::add.
// It is crucial that we do not block before the thread is
// added to the Threads list for if a GC happens, then the java_thread oop
// will not be visited by GC.
Threads::add(this);
}
void set_threadObj(oop p) { _threadObj = p; }
//设置eetop属性
void java_lang_Thread::set_thread(oop java_thread, JavaThread* thread) {
java_thread->address_field_put(_eetop_offset, (address)thread);
}
//获取priority属性,默认是继承父线程的的线程优先级
ThreadPriority java_lang_Thread::priority(oop java_thread) {
return (ThreadPriority)java_thread->int_field(_priority_offset);
}
void Thread::set_priority(Thread* thread, ThreadPriority priority) {
trace("set priority", thread);
debug_only(check_for_dangling_thread_pointer(thread);)
//设置线程优先级
(void)os::set_priority(thread, priority);
}
OSReturn os::set_priority(Thread* thread, ThreadPriority p) {
if (p >= MinPriority && p <= MaxPriority) {
//将Java的优先级映射成原生线程的优先级
int priority = java_to_os_priority[p];
return set_native_priority(thread, priority);
} else {
assert(false, "Should not happen");
return OS_ERR;
}
}
//force_daemon默认为false
void Threads::add(JavaThread* p, bool force_daemon) {
// The threads lock must be owned at this point
assert_locked_or_safepoint(Threads_lock);
// 初始化GC相关的队列
p->initialize_queues();
//插入到thread_list链表中
p->set_next(_thread_list);
_thread_list = p;
_number_of_threads++;
oop threadObj = p->threadObj();
bool daemon = true;
if ((!force_daemon) && (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj))) {
//非daemon线程计数加1
_number_of_non_daemon_threads++;
daemon = false;
}
//ThreadService维护的相关计数加1
ThreadService::add_thread(p, daemon);
Events::log(p, "Thread added: " INTPTR_FORMAT, p);
}
bool java_lang_Thread::is_daemon(oop java_thread) {
return java_thread->bool_field(_daemon_offset) != 0;
}
void Thread::start(Thread* thread) {
trace("start", thread);
//DisableStartThread默认是false
if (!DisableStartThread) {
if (thread->is_Java_thread()) {
//如果是java线程,设置线程状态
java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
java_lang_Thread::RUNNABLE);
}
//启动原生线程
os::start_thread(thread);
}
}
void os::start_thread(Thread* thread) {
MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);
OSThread* osthread = thread->osthread();
osthread->set_state(RUNNABLE);
//唤醒之前创建的在startThread_lock上等待的子线程,开始执行JavaThread的run方法
pd_start_thread(thread);
}
void os::pd_start_thread(Thread* thread) {
OSThread * osthread = thread->osthread();
assert(osthread->get_state() != INITIALIZED, "just checking");
//唤醒在startThread_lock上等待的线程
Monitor* sync_with_child = osthread->startThread_lock();
MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
sync_with_child->notify();
}
OSThread的具体执行逻辑就是在调用pthread_create函数时传入的java_start函数,该函数会负责初始化OSThread,初始化完成将状态设置为INITIALIZED并唤醒startThread_lock上等待的负责创建OSThread的线程,然后继续等待直到OSThread的状态不再是INITIALIZED。这时创建OSThread的线程发现OSThread已经初始化完成就会退出OSThread的创建方法,然后进入启动OSThread执行的方法,该方法将状态置为RUNNABLE,并唤醒startThread_lock等待的线程。这是创建的子线程就会开始正常执行,调用JavaThread的run方法,该方法的实现如下:
void JavaThread::run() {
//初始TLAB
this->initialize_tlab();
//记录栈基地址
this->record_base_of_stack_pointer();
//初始化OSThread的栈帧
this->record_stack_base_and_size();
//初始化ThreadLocalStorage
this->initialize_thread_local_storage();
//创建stack_guard_pages
this->create_stack_guard_pages();
//空实现
this->cache_global_variables();
//修改线程状态,注意此时会检查是否进入安全点同步,如果是则阻塞当前线程
ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm);
assert(JavaThread::current() == this, "sanity check");
assert(!Thread::current()->owns_locks(), "sanity check");
DTRACE_THREAD_PROBE(start, this);
//设置JNIHandleBlock
this->set_active_handles(JNIHandleBlock::allocate_block());
if (JvmtiExport::should_post_thread_life()) {
JvmtiExport::post_thread_start(this);
}
EventThreadStart event;
if (event.should_commit()) {
event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
event.commit();
}
//执行具体的run方法并在执行完成销毁当前实例
thread_main_inner();
}
void JavaThread::thread_main_inner() {
assert(JavaThread::current() == this, "sanity check");
assert(this->threadObj() != NULL, "just checking");
//如果没有待处理异常且没有被中止
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的run方法
this->entry_point()(this, this);
}
//run方法执行完成,准备退出线程
this->exit(false);
//释放JavaThread对应的内存
delete this;
}
//stillborn表示线程是否被中止,调用stop方法时会将该属性置为true
bool java_lang_Thread::is_stillborn(oop java_thread) {
return java_thread->bool_field(_stillborn_offset) != 0;
}
2、join
join方法用于等待创建的线程执行完成并退出,该方法有三个版本,一个是无参数的,表示无期限等待,一个是有一个参数,指定等待的毫秒数,一个是有两个参数,指定等待的毫秒数和纳秒数,其实现如下:
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
//参数非法
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
//isAlive是一个本地方法
while (isAlive()) {
//无期限等待
wait(0);
}
} else {
while (isAlive()) {
//now初始是0
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
//被唤醒后更新now,表示已等待的时间
now = System.currentTimeMillis() - base;
}
}
}
public final synchronized void join(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
//实际没有处理纳秒,还是将其四舍五入成毫秒了
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis);
}
注意join方法是synchronized方法,当Java线程退出的时候会在JavaThread::exit方法中调用ObjectLocker的notify_all方法,唤醒所有在该Thread实例关联的重量级锁上等待的线程,即调用join方法的线程,该方法的实现如下:
其调用链如下:
调用join方法的线程判断目标线程不存在了就会终止while循环,退出join方法。判断Java线程是否存活的本地方法isAlive的实现如下:
JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_IsThreadAlive");
//从JNI引用中解析出对应的Thread实例oop
oop thread_oop = JNIHandles::resolve_non_null(jthread);
return java_lang_Thread::is_alive(thread_oop);
JVM_END
bool java_lang_Thread::is_alive(oop java_thread) {
//获取关联的JavaThread,如果为NULL表示该线程已经退出
JavaThread* thr = java_lang_Thread::thread(java_thread);
return (thr != NULL);
}
//在调用ObjectLocker的notify_all方法前会将该属性置为NULL
JavaThread* java_lang_Thread::thread(oop java_thread) {
return (JavaThread*)java_thread->address_field(_eetop_offset);
}
用于设置eetop属性的set_thread方法的调用链如下:
其中prepare是线程启动时调用的,ensure_join是线程退出时调用的,该方法的实现如下:
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "java thread object must exist");
//创建ObjectLocker
ObjectLocker lock(threadObj, thread);
//清除待处理异常,因为线程准备退出了
thread->clear_pending_exception();
//设置线程状态为TERMINATED
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
//将eetop属性置为NULL,这样is_alive方法就会返回false
java_lang_Thread::set_thread(threadObj(), NULL);
//唤醒所有在该thread oop关联的重量级锁上等待的线程
lock.notify_all(thread);
//清除待处理异常
thread->clear_pending_exception();
}
3、sleep
sleep是让当前线程休眠,有两个版本,一个指定休眠的毫秒数,一个指定休眠的毫秒数和纳秒数,同join方法,纳秒数实际会四舍五入成毫秒数,最终都是调用第一个版本,该方法是一个本地方法,其实现如下:
JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
JVMWrapper("JVM_Sleep");
if (millis < 0) {
//参数异常
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
}
if (Thread::is_interrupted (THREAD, true) && !HAS_PENDING_EXCEPTION) {
//如果已经被中断则抛出异常
THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
}
//增加线程sleep的次数,并启动计入sleep耗时的计时器
JavaThreadSleepState jtss(thread);
EventThreadSleep event;
if (millis == 0) {
//x86下ConvertSleepToYield为true
if (ConvertSleepToYield) {
os::yield();
} else {
ThreadState old_state = thread->osthread()->get_state();
thread->osthread()->set_state(SLEEPING);
os::sleep(thread, MinSleepInterval, false);
thread->osthread()->set_state(old_state);
}
} else {
ThreadState old_state = thread->osthread()->get_state();
//将osthread的状态置为SLEEPING
thread->osthread()->set_state(SLEEPING);
if (os::sleep(thread, millis, true) == OS_INTRPT) {
if (!HAS_PENDING_EXCEPTION) {
//sleep被中断了
if (event.should_commit()) {
//发布事件
event.set_time(millis);
event.commit();
}
//抛出异常
THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
}
}
//恢复原来的状态
thread->osthread()->set_state(old_state);
}
if (event.should_commit()) {
event.set_time(millis);
event.commit();
}
JVM_END
//返回当前线程是否已经被中断
bool Thread::is_interrupted(Thread* thread, bool clear_interrupted) {
trace("is_interrupted", thread);
debug_only(check_for_dangling_thread_pointer(thread);)
return os::is_interrupted(thread, clear_interrupted);
}
bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
assert(Thread::current() == thread || Threads_lock->owned_by_self(),
"possibility of dangling Thread pointer");
OSThread* osthread = thread->osthread();
bool interrupted = osthread->interrupted();
if (interrupted && clear_interrupted) {
//如果需要清除interrupted标识
osthread->set_interrupted(false);
}
return interrupted;
}
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
assert(thread == Thread::current(), "thread consistency check");
ParkEvent * const slp = thread->_SleepEvent ;
slp->reset() ;
OrderAccess::fence() ;
if (interruptible) {
jlong prevtime = javaTimeNanos();
for (;;) {
if (os::is_interrupted(thread, true)) {
//如果线程已被中断
return OS_INTRPT;
}
jlong newtime = javaTimeNanos();
if (newtime - prevtime < 0) {
//linux不支持monotonic_clock
assert(!Linux::supports_monotonic_clock(), "time moving backwards");
} else {
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
}
if(millis <= 0) {
//休眠的时间已过
return OS_OK;
}
prevtime = newtime;
{
assert(thread->is_Java_thread(), "sanity check");
JavaThread *jt = (JavaThread *) thread;
//修改线程状态为_thread_blocked,等代码块退出将其恢复成_thread_in_vm,转换过程中会检查安全点
ThreadBlockInVM tbivm(jt);
//将OSThread的状态修改为CONDVAR_WAIT,代码块退出时恢复原来的状态
OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
jt->set_suspend_equivalent();
//让当前线程休眠,如果线程被唤醒了则继续for循环
slp->park(millis);
jt->check_and_wait_while_suspended();
}
}
} else {
OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
jlong prevtime = javaTimeNanos();
//逻辑同上只是不需要检查目标线程是否中断,使用与sleep时间特别短的情形,如sleep(0)
for (;;) {
jlong newtime = javaTimeNanos();
if (newtime - prevtime < 0) {
assert(!Linux::supports_monotonic_clock(), "time moving backwards");
} else {
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
}
if(millis <= 0) break ;
prevtime = newtime;
slp->park(millis);
}
return OS_OK ;
}
}
其中JavaThreadSleepState通过构造和析构函数来统计线程休眠的次数和累计时间,其定义如下:
4、interrupt / interrupted
interrupt方法用于中断某个处于阻塞状态的线程,如调用sleep方法后被阻塞的线程,中断后该线程就会抛出InterruptedException异常;interrupted方法用于判断某个线程是否被中断了,其实现如下:
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
//blockerLock就是操作blocker的锁
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
//可中断IO在开始执行IO前会设置blocker,正常情形下为null
interrupt0(); // Just to set the interrupt flag
//调用其interrupt方法
b.interrupt(this);
return;
}
}
interrupt0();
}
public static boolean interrupted() {
//currentThread和isInterrupted都是本地方法
return currentThread().isInterrupted(true);
}
搜索Interruptible接口的实现类,如下:
这两个都是用匿名内部类实现的该接口,以AbstractSelector为例说明,其实现如下:
其中blockedOn方法会调用Thread类的blockedOn来设置blocker属性,其实现如下:
该方法只能在包内访问,不是public的,所以AbstractInterruptibleChannel的blockedOn借助了sun的特殊方法,其实现如下:
currentThread,isInterrupted和interrupt0三个本地方法的实现如下:
JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
JVMWrapper("JVM_CurrentThread");
//thread是JVM_ENTRY中获取的,获取其关联的Thread实例oop
oop jthread = thread->threadObj();
assert (thread != NULL, "no current thread!");
//返回该实例oop,注意需要将其包裹成JNI本地引用
return JNIHandles::make_local(env, jthread);
JVM_END
#define JVM_ENTRY(result_type, header) \
extern "C" { \
result_type JNICALL header { \
//从JNIEnv中获取当前的JavaThread指针
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
//切换线程状态,需要检查安全点
ThreadInVMfromNative __tiv(thread); \
debug_only(VMNativeEntryWrapper __vew;) \
VM_ENTRY_BASE(result_type, header, thread)
static JavaThread* thread_from_jni_environment(JNIEnv* env) {
//每个JavaThread都有一个单独的JNIEnv实例,此处是根据env的地址和其在JavaThread中的属性偏移量倒推出JavaThread的地址
JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset()));
if (thread_from_jni_env->is_terminated()) {
//如果JVM正在退出的过程中,则阻塞当前线程
thread_from_jni_env->block_if_vm_exited();
//返回NULL
return NULL;
} else {
return thread_from_jni_env;
}
}
JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
JVMWrapper("JVM_IsInterrupted");
//获取对应的Thread实例
oop java_thread = JNIHandles::resolve_non_null(jthread);
//如果就是当前线程,则不需要获取锁,否则需要获取Threads_lock锁
MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
//获取关联的JavaThread
JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
if (thr == NULL) {
return JNI_FALSE;
} else {
//JavaThread不为空,判断其是否被中断,clear_interrupted默认为true,此处就是1
return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);
}
JVM_END
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_Interrupt");
//获取对应的Thread实例
oop java_thread = JNIHandles::resolve_non_null(jthread);
//如果就是当前线程,则不需要获取锁,否则需要获取Threads_lock锁
MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
//获取关联的JavaThread
JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
if (thr != NULL) {
Thread::interrupt(thr);
}
JVM_END
void Thread::interrupt(Thread* thread) {
trace("interrupt", thread);
debug_only(check_for_dangling_thread_pointer(thread);)
os::interrupt(thread);
}
void os::interrupt(Thread* thread) {
assert(Thread::current() == thread || Threads_lock->owned_by_self(),
"possibility of dangling Thread pointer");
OSThread* osthread = thread->osthread();
if (!osthread->interrupted()) {
//将interrupted标识置为true
osthread->set_interrupted(true);
OrderAccess::fence();
ParkEvent * const slp = thread->_SleepEvent ;
//唤醒在_SleepEvent上等待的线程,_SleepEvent用于实现线程sleep
if (slp != NULL) slp->unpark() ;
}
//唤醒在parker上等待的线程,parker用于实现Unsafe的park和unpark方法
if (thread->is_Java_thread())
((JavaThread*)thread)->parker()->unpark();
ParkEvent * ev = thread->_ParkEvent ;
//唤醒在_ParkEvent上等待的线程,_ParkEvent用于实现synchronized关键字
if (ev != NULL) ev->unpark() ;
}
从上述实现可知,interrupt方法会将OSThread的中断标识置为true,同时唤醒在因为sleep、synchronized关键字或者Java的Lock锁而阻塞等待的线程,注意该方法并不会如字面所说的会中断正在执行中的线程。
5、yeild
yeild就是一个本地方法,用于让出当前线程的CPU时间片,其实现如下:
JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))
JVMWrapper("JVM_Yield");
//如果操作系统不支持yeild则返回
if (os::dont_yield()) return;
//ConvertYieldToSleep默认为false
if (ConvertYieldToSleep) {
os::sleep(thread, MinSleepInterval, false);
} else {
os::yield();
}
JVM_END
void os::yield() {
//sched_yield()是Linux的API,会让出当前线程的CPU占有权,然后把线程放到调度队列的尾端,即优先调度其他的线程
//给他们分配CPU时间片
sched_yield();
}
6、holdsLock
holdsLock是一个本地方法,用于判断当前线程是否持有某个对象的锁,其实现如下:
JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))
JVMWrapper("JVM_HoldsLock");
assert(THREAD->is_Java_thread(), "sanity check");
if (obj == NULL) {
//obj为空抛出异常
THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
}
Handle h_obj(THREAD, JNIHandles::resolve(obj));
return ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, h_obj);
JVM_END
bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread,
Handle h_obj) {
if (UseBiasedLocking) {
//撤销偏向锁,如果该偏向锁正在使用,则会被升级成轻量级锁
BiasedLocking::revoke_and_rebias(h_obj, false, thread);
assert(!h_obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
assert(thread == JavaThread::current(), "Can only be called on current thread");
oop obj = h_obj();
//获取对象头,如果正在锁膨胀,则通过自旋,yeild,park等方式等待锁膨胀完成
markOop mark = ReadStableMark (obj) ;
if (mark->has_locker()) {
//如果是轻量级锁状态,则判断对象头包含的locker是否属于当前线程
return thread->is_lock_owned((address)mark->locker());
}
if (mark->has_monitor()) {
//如果是重量级锁,则判断owner属性是否是当前线程指针
ObjectMonitor* monitor = mark->monitor();
return monitor->is_entered(thread) != 0 ;
}
//无锁状态
assert(mark->is_neutral(), "sanity check");
return false;
}
inline intptr_t ObjectMonitor::is_entered(TRAPS) const {
if (THREAD == _owner || THREAD->is_lock_owned((address) _owner)) {
return 1;
}
return 0;
}
7、setPriority
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();
}
//修改priority属性并调用setPriority0方法
setPriority0(priority = newPriority);
}
}
JavaThread定义的线程优先级枚举常量如下:
setPriority0是一个本地方法,其实现如下:
JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))
JVMWrapper("JVM_SetThreadPriority");
//获取Threads_lock锁
MutexLocker ml(Threads_lock);
//获取关联的Thread实例oop
oop java_thread = JNIHandles::resolve_non_null(jthread);
//设置Thread实例的priority属性
java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);
//获取关联的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);
}
JVM_END
void java_lang_Thread::set_priority(oop java_thread, ThreadPriority priority) {
java_thread->int_field_put(_priority_offset, priority);
}
设置OSThread的线程优先级前会将Java线程的优先级映射成OSThread的线程优先级,其映射关系如下:
Java线程的优先级就是上面数组的索引,比如NormPriority对应的OSThread的优先级就是0。
Java线程的优先级默认情况是继承自父线程的优先级,那么第一个创建的main线程的优先级是啥了?参考JVM启动过程中用于创建main线程的create_initial_thread方法的实现,如下:
static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) {
//加载并初始化java_lang_Thread类
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
instanceKlassHandle klass (THREAD, k);
//分配一个instanceHandle
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
//Thread实例oop保存关联的JavaThread
java_lang_Thread::set_thread(thread_oop(), thread);
//设置线程优先级为NormPriority
java_lang_Thread::set_priority(thread_oop(), NormPriority);
//JavaThread保存关联的Thread实例oop
thread->set_threadObj(thread_oop());
//初始化一个字符串main
Handle string = java_lang_String::create_from_str("main", CHECK_NULL);
JavaValue result(T_VOID);
//调用Thread的构造方法,创建的Thread实例保存在thread_oop中
JavaCalls::call_special(&result, thread_oop,
klass,
vmSymbols::object_initializer_name(),
vmSymbols::threadgroup_string_void_signature(),
thread_group,
string,
CHECK_NULL);
return thread_oop();
}
main线程的优先级就是NormPriority,由该线程创建的子线程的优先级就默认是NormPriority。
转载:https://blog.csdn.net/qq_31865983/article/details/105174567