public Thread() { this(null, null, "Thread-" + nextThreadNum(), 0); }
public Thread(ThreadGroup group, Runnable target, String name, long stackSize) { this(group, target, name, stackSize, null, true); }
private Thread(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name; Thread parent = currentThread(); if (g == null) { if (security != null) { g = security.getThreadGroup(); } if (g == null) { */ g = parent.getThreadGroup(); // } } g.checkAccess(); /* * Do we have the required permissions? * if (security != null) { if (isCCLOverridden(getClass())) { security.checkPermission( SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION); } } */ g.addUnstarted(); this.group = g; this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); // Android-changed: Moved into init2(Thread, boolean) helper method. /* if (security == null || isCCLOverridden(parent.getClass())) this.contextClassLoader = parent.getContextClassLoader(); else this.contextClassLoader = parent.contextClassLoader; this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext(); */ this.target = target; init2(parent, inheritThreadLocals); /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; /* Set thread ID */ this.tid = nextThreadID(); }
private void init2(Thread parent, boolean inheritThreadLocals) { this.contextClassLoader = parent.getContextClassLoader(); this.inheritedAccessControlContext = AccessController.getContext(); if (inheritThreadLocals && parent.inheritableThreadLocals != null) { this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); } }
可以发现构造函数只是定义了线程组信息和一些本线程信息,并且调用了ThreadLocal.createInheritedMap(parent.inheritableThreadLocals)
public class ThreadLocal<T> {
static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) { return new ThreadLocalMap(parentMap); }
}
private ThreadLocalMap(ThreadLocalMap parentMap) {
Entry[] parentTable = parentMap.table;
int len = parentTable.length;
setThreshold(len);
table = new Entry[len];
for (int j = 0; j < len; j++) {
Entry e = parentTable[j];
if (e != null) {
@SuppressWarnings("unchecked")
ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
if (key != null) {
Object value = key.childValue(e.value);
//为线程创建一个新的ThreadLocal Entry,用来存储线程和Looper
Entry c = new Entry(key, value);
int h = key.threadLocalHashCode & (len - 1);
while (table[h] != null)
h = nextIndex(h, len);
table[h] = c;
size++;
}
}
}
}
所以new一个线程的时候,创建了线程信息、线程组信息、ThreadLocal Entry。但是线程未真正的创建出来,也未启动。
我们接着看线程的启动 Thread.start()
public synchronized void start() { if (started) throw new IllegalThreadStateException(); group.add(this);//把当前线程添加到线程组 started = false; try { nativeCreate(this, stackSize, daemon); 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 */ } } }
nativeCreate是native方法,是实际创建线程的代码实现 private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
C层实现在 /art/runtime/native/java_lang_Thread.cc 中
动态注册
static JNINativeMethod gMethods[] = {
198 FAST_NATIVE_METHOD(Thread, currentThread, "()Ljava/lang/Thread;"),
199 FAST_NATIVE_METHOD(Thread, interrupted, "()Z"),
200 FAST_NATIVE_METHOD(Thread, isInterrupted, "()Z"),
201 NATIVE_METHOD(Thread, nativeCreate, "(Ljava/lang/Thread;JZ)V"),
202 NATIVE_METHOD(Thread, nativeGetStatus, "(Z)I"),
203 NATIVE_METHOD(Thread, holdsLock, "(Ljava/lang/Object;)Z"),
204 FAST_NATIVE_METHOD(Thread, interrupt0, "()V"),
205 NATIVE_METHOD(Thread, setNativeName, "(Ljava/lang/String;)V"),
206 NATIVE_METHOD(Thread, setPriority0, "(I)V"),
207 FAST_NATIVE_METHOD(Thread, sleep, "(Ljava/lang/Object;JI)V"),
208 NATIVE_METHOD(Thread, yield, "()V"),
209 };
NATIVE_METHOD是宏定义 #ifndef NATIVE_METHOD 21 #define NATIVE_METHOD(className, functionName, signature) \ 22 { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) } 23 #endif
宏展开后得知方法名为Thread_nativeCreate
static void Thread_nativeCreate(JNIEnv* env, jclass, jobject java_thread, jlong stack_size,
51 jboolean daemon) {
52 // There are sections in the zygote that forbid thread creation.
53 Runtime* runtime = Runtime::Current();
54 if (runtime->IsZygote() && runtime->IsZygoteNoThreadSection()) {//zygote进程禁用多线程
55 jclass internal_error = env->FindClass("java/lang/InternalError");
56 CHECK(internal_error != nullptr);
57 env->ThrowNew(internal_error, "Cannot create threads in zygote");
58 return;
59 }
60
61 Thread::CreateNativeThread(env, java_thread, stack_size, daemon == JNI_TRUE);
62 }
CreateNativeThread源码如下:
void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) {
823 CHECK(java_peer != nullptr);
824 Thread* self = static_cast<JNIEnvExt*>(env)->GetSelf();
825
826 if (VLOG_IS_ON(threads)) {
827 ScopedObjectAccess soa(env);
828
829 ArtField* f = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_name);
830 ObjPtr<mirror::String> java_name =
831 f->GetObject(soa.Decode<mirror::Object>(java_peer))->AsString();
832 std::string thread_name;
833 if (java_name != nullptr) {
834 thread_name = java_name->ToModifiedUtf8();
835 } else {
836 thread_name = "(Unnamed)";
837 }
838
839 VLOG(threads) << "Creating native thread for " << thread_name;
840 self->Dump(LOG_STREAM(INFO));
841 }
842
843 Runtime* runtime = Runtime::Current();
844
845 // Atomically start the birth of the thread ensuring the runtime isn't shutting down.
846 bool thread_start_during_shutdown = false;
847 {
848 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
849 if (runtime->IsShuttingDownLocked()) {
850 thread_start_during_shutdown = true;
851 } else {
852 runtime->StartThreadBirth();
853 }
854 }
855 if (thread_start_during_shutdown) {
856 ScopedLocalRef<jclass> error_class(env, env->FindClass("java/lang/InternalError"));
857 env->ThrowNew(error_class.get(), "Thread starting during runtime shutdown");
858 return;
859 }
860 //new一个C层的Thread
861 Thread* child_thread = new Thread(is_daemon);
862 // Use global JNI ref to hold peer live while child thread starts.
863 child_thread->tlsPtr_.jpeer = env->NewGlobalRef(java_peer);
864 stack_size = FixStackSize(stack_size);
868 env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer,
869 reinterpret_cast<jlong>(child_thread));
873 std::string error_msg;
874 std::unique_ptr<JNIEnvExt> child_jni_env_ext(
875 JNIEnvExt::Create(child_thread, Runtime::Current()->GetJavaVM(), &error_msg));
876
877 int pthread_create_result = 0;
878 if (child_jni_env_ext.get() != nullptr) {
879 pthread_t new_pthread;
880 pthread_attr_t attr;
881 child_thread->tlsPtr_.tmp_jni_env = child_jni_env_ext.get();
882 CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), "new thread");
883 CHECK_PTHREAD_CALL(pthread_attr_setdetachstate, (&attr, PTHREAD_CREATE_DETACHED),
884 "PTHREAD_CREATE_DETACHED");
885 CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), stack_size);
//实际上就是调用了C层的pthread_create
886 pthread_create_result = pthread_create(&new_pthread,
887 &attr,
888 Thread::CreateCallback,
889 child_thread);
890 CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), "new thread");
891
892 if (pthread_create_result == 0) {
897 child_jni_env_ext.release(); // NOLINT pthreads API.
898 return;
899 }
900 }
903 {
904 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
905 runtime->EndThreadBirth();
906 }
909 child_thread->DeleteJPeer(env);
910 delete child_thread;
911 child_thread = nullptr;
912 // TODO: remove from thread group?
913 env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer, 0);
914 {
915 std::string msg(child_jni_env_ext.get() == nullptr ?
916 StringPrintf("Could not allocate JNI Env: %s", error_msg.c_str()) :
917 StringPrintf("pthread_create (%s stack) failed: %s",
918 PrettySize(stack_size).c_str(), strerror(pthread_create_result)));
919 ScopedObjectAccess soa(env);
920 soa.Self()->ThrowOutOfMemoryError(msg.c_str());
921 }
922 }
调用了C层的 pthread_create之后回调到了 Thread::CreateCallback
void* Thread::CreateCallback(void* arg) {
597 Thread* self = reinterpret_cast<Thread*>(arg);
598 Runtime* runtime = Runtime::Current();
599 if (runtime == nullptr) {
600 LOG(ERROR) << "Thread attaching to non-existent runtime: " << *self;
601 return nullptr;
602 }
603 {
604 // TODO: pass self to MutexLock - requires self to equal Thread::Current(), which is only true
605 // after self->Init().
606 MutexLock mu(nullptr, *Locks::runtime_shutdown_lock_);
607 // Check that if we got here we cannot be shutting down (as shutdown should never have started
608 // while threads are being born).
609 CHECK(!runtime->IsShuttingDownLocked());
610 // Note: given that the JNIEnv is created in the parent thread, the only failure point here is
611 // a mess in InitStackHwm. We do not have a reasonable way to recover from that, so abort
612 // the runtime in such a case. In case this ever changes, we need to make sure here to
613 // delete the tmp_jni_env, as we own it at this point.
614 CHECK(self->Init(runtime->GetThreadList(), runtime->GetJavaVM(), self->tlsPtr_.tmp_jni_env));
615 self->tlsPtr_.tmp_jni_env = nullptr;
616 Runtime::Current()->EndThreadBirth();
617 }
618 {
619 ScopedObjectAccess soa(self);
620 self->InitStringEntryPoints();
621
622 // Copy peer into self, deleting global reference when done.
623 CHECK(self->tlsPtr_.jpeer != nullptr);
624 self->tlsPtr_.opeer = soa.Decode<mirror::Object>(self->tlsPtr_.jpeer).Ptr();
625 // Make sure nothing can observe both opeer and jpeer set at the same time.
626 self->DeleteJPeer(self->GetJniEnv());
627 self->SetThreadName(self->GetThreadName()->ToModifiedUtf8().c_str());
628
629 ArtField* priorityField = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_priority);
630 self->SetNativePriority(priorityField->GetInt(self->tlsPtr_.opeer));
631 //Runtime执行线程启动完毕回调
632 runtime->GetRuntimeCallbacks()->ThreadStart(self);
633
634 // Unpark ourselves if the java peer was unparked before it started (see
635 // b/28845097#comment49 for more information)
636
637 ArtField* unparkedField = jni::DecodeArtField(
638 WellKnownClasses::java_lang_Thread_unparkedBeforeStart);
639 bool should_unpark = false;
640 {
641 // Hold the lock here, so that if another thread calls unpark before the thread starts
642 // we don't observe the unparkedBeforeStart field before the unparker writes to it,
643 // which could cause a lost unpark.
644 art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
645 should_unpark = unparkedField->GetBoolean(self->tlsPtr_.opeer) == JNI_TRUE;
646 }
647 if (should_unpark) {
648 self->Unpark();
649 }
650 // Invoke the 'run' method of our java.lang.Thread.
651 ObjPtr<mirror::Object> receiver = self->tlsPtr_.opeer;
652 jmethodID mid = WellKnownClasses::java_lang_Thread_run;
653 ScopedLocalRef<jobject> ref(soa.Env(), soa.AddLocalReference<jobject>(receiver));
654 InvokeVirtualOrInterfaceWithJValues(soa, ref.get(), mid, nullptr);
655 }
656 // Detach and delete self.
657 Runtime::Current()->GetThreadList()->Unregister(self);
658
659 return nullptr;
660 }