線程 調(diào)用
star()
的過程分析:
public static void main(String[] args) {
new Thread(()->{
System.out.println("啟動(dòng)一個(gè)新的線程"+Thread.currentThread().getName());
}).start();
}
啟動(dòng)一個(gè)新的線程Thread-0
Process finished with exit code 0
當(dāng) Java 線程創(chuàng)建好后,調(diào)用
start()
方法就會(huì)啟動(dòng)一個(gè)線程柳弄,那start()
是怎么實(shí)現(xiàn)的呢舶胀?源碼如下:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
分析以上代碼 發(fā)現(xiàn) 最終調(diào)用了
start0()
這個(gè)方法,找到start0();
代碼:
private native void start0();
原來是
native
方法语御,打開 jdk 源碼 找到start0
定義和實(shí)現(xiàn):
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
};
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;
set_entry_point(entry_point);
// Create the native thread itself.
// %note runtime_23
os::ThreadType thr_type = os::java_thread;
thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread : os::java_thread;
// 創(chuàng)建線程
os::create_thread(this, thr_type, stack_sz);
_safepoint_visible = false;
// The _osthread may be NULL here because we ran out of memory (too many threads active).
// We need to throw and OutOfMemoryError - however we cannot do this here because the caller
// may hold a lock and all locks must be unlocked before throwing the exception (throwing
// the exception consists of creating the exception object & initializing it, initialization
// will leave the VM via a JavaCall and then all locks must be unlocked).
//
// The thread is still suspended when we reach here. Thread must be explicit started
// by creator! Furthermore, the thread must also explicitly be added to the Threads list
// by calling Threads:add. The reason why this is not done here, is because the thread
// object must be fully initialized (take a look at JVM_Start)
}
通過閱讀以上代碼發(fā)現(xiàn)
os::create_thread(this, thr_type, stack_sz);
才是調(diào)用系統(tǒng)內(nèi)核創(chuàng)建線程,找到對(duì)應(yīng)Linux 線程創(chuàng)建實(shí)現(xiàn):
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
assert(thread->osthread() == NULL, "caller responsible");
// Allocate the OSThread object
OSThread* osthread = new OSThread(NULL, NULL);
if (osthread == NULL) {
return false;
}
峻贮。。应闯。。挂捻。碉纺。
// 創(chuàng)建線程
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
。刻撒。骨田。。声怔。态贤。
assert(state == INITIALIZED, "race condition");
return true;
}
通過閱讀以上代碼 發(fā)現(xiàn) 主要就 通過
pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread)
來創(chuàng)建線程,第三個(gè)參數(shù)是線程運(yùn)行函數(shù)的地址醋火,最后一個(gè)參數(shù)是運(yùn)行函數(shù)的參數(shù)悠汽。pthread_create 定義
static void *java_start(Thread *thread) {
// Try to randomize the cache line index of hot stack frames.
// This helps when threads of the same stack traces evict each other's
// cache lines. The threads can be either from the same JVM instance, or
// from different JVM instances. The benefit is especially true for
// processors with hyperthreading technology.
static int counter = 0;
int pid = os::current_process_id();
alloca(((pid ^ counter++) & 7) * 128);
ThreadLocalStorage::set_thread(thread);
OSThread* osthread = thread->osthread();
Monitor* sync = osthread->startThread_lock();
// non floating stack LinuxThreads needs extra check, see above
if (!_thread_safety_check(thread)) {
// notify parent thread
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
osthread->set_state(ZOMBIE);
sync->notify_all();
return NULL;
}
// thread_id is kernel thread id (similar to Solaris LWP id)
osthread->set_thread_id(os::Linux::gettid());
if (UseNUMA) {
int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) {
thread->set_lgrp_id(lgrp_id);
}
}
// initialize signal mask for this thread
os::Linux::hotspot_sigmask(thread);
// initialize floating point control register
os::Linux::init_thread_fpu_state();
// handshaking with parent thread
{
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
// notify parent thread
osthread->set_state(INITIALIZED);
sync->notify_all();
// wait until os::start_thread()
while (osthread->get_state() == INITIALIZED) {
sync->wait(Mutex::_no_safepoint_check_flag);
}
}
// call one more level start routine
// 調(diào)用JavaThread::run()方法
thread->run();
return 0;
}
通過以上代碼發(fā)現(xiàn) 最后調(diào)用
thread->run();
找到對(duì)應(yīng)的實(shí)現(xiàn):
void JavaThread::run() {
// initialize thread-local alloc buffer related fields
// 初始化Thread_local
this->initialize_tlab();
// used to test validitity of stack trace backs
this->record_base_of_stack_pointer();
// Record real stack base and size.
this->record_stack_base_and_size();
// Initialize thread local storage; set before calling MutexLocker
// 初始化 ThreadLocal 存儲(chǔ)
this->initialize_thread_local_storage();
this->create_stack_guard_pages();
this->cache_global_variables();
// Thread is now sufficient initialized to be handled by the safepoint code as being
// in the VM. Change thread state from _thread_new to _thread_in_vm
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);
// This operation might block. We call that after all safepoint checks for a new thread has
// been completed.
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();
}
// We call another function to do the rest so we are sure that the stack addresses used
// from there will be lower than the stack base just computed
// 判斷 run() 是否執(zhí)行完畢,然后退出線程
thread_main_inner();
}
通過閱讀以上代碼發(fā)現(xiàn):程序在最后執(zhí)行
thread_main_inner();
該 方法 主要書判斷 當(dāng)前線程 是否執(zhí)行完畢芥驳,如果執(zhí)行完畢柿冲,清除線程,并喚醒等待線程隊(duì)列中的一個(gè)線程兆旬。