Java线程基础-Thread ThreadGroup ThreadLocal ThreadGroupContext 之Thread (一)

    Thread、ThreadGroup ThreadLocal以及ThreadGroupContext是线程相关的Java知识,为什么会开这个题是因为在上一章的时候出现ThreadGroupContext这个东西,想对他进行学习并且能实践到实际的应用场景中。

1.Thread

1.1 简述Thread

  Thread就是线程,线程解释我觉得可以从外到内,外是就是一台电脑,我们的要使用我们电脑大部分人都   是先具备一个基本的操作系统,比如windows、linux、macos,我们通过操作系统看视频、上微信,其实可以看成称看视频以及上微信是两个应用任务,操作系统通过CPU调度任务执行,让我们看起来可以同时看视频跟上微信,一个任务就是一个进程,而线程就是进程的子单位,相当于你用用视频软件看视频是一个线程,你用视频软件发视频评论是一个线程,你可以在同一个视频软件同时看视频跟发表评论。
    在Java里面,一个Java程序会开启一个JVM进程,JVM它是由软件技术模拟出计算机运行的一个虚拟的计算机。我们都知道Java的程序需要经过编译后,产生.Class字节码文件,JVM才能识别并运行它,JVM针对每个操作系统开发其对应的解释器,所以只要其操作系统有对应版本的JVM,那么这份Java编译后的代码就能够运行起来,这就是Java能一次编译,到处运行的原因。
    JVM结构如下图所示

JVM 线程共享区: 堆、方法区
JVM 线程独占区:虚拟机栈、本地方法栈、程序计数器

1.2 Thread 基础操作

在Java里面,我们用基础的Java程序说明Thread的应用。

             log("主线程执行开始");
               new Thread(() -> {
                   try{
                       Thread.sleep(300);
                   }catch (InterruptedException  e){
                       e.printStackTrace();
                   }
                   log("运行任务1结束...");
               }).start();
               new Thread(() -> {
                   try{
                          Thread.sleep(200);
                       }catch (InterruptedException  e){
                           e.printStackTrace();
                       }
                   log("运行任务2结束...");
               }).start();
               log("主线程结束");


控制台输出结果如下:
在这里插入图片描述

  上面程序是在主线程,开始了两个子线程任务1跟任务2,任务1主要休眠300ms,任务2休眠200ms,从控制台输出结果来看,主线程的结束并不会影响子线程1,2的执行,子线程各自执行也是独立的并不是串联执行,在Java程序中,多线程的应用十分地广泛,让java程序更快地处理任务,达到用户需求。

1.3 Thread启动原理

1.3.1 thread.start()启动线程

&nbsp&nbsp 一个Thread的启动是通过触发Thread.start()的方法
在这里插入图片描述

真正启动线程的时候start0()这个方法,在之前是将线程放进ThreadGroup中,也就是我们待会讲的,这里不细说。之后就是修改线程的启动状态。
start0 的定义如下:

    private native void start0();

1.3.2 创建底层线程对象

一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。在Thread创建的时候先跑的static方法,registerNatives()
在这里插入图片描述

而本地方法 registerNatives 是定义在 Thread.c 文件中的。Thread.c 是个很小的文件,它定义了各个操作系统平台都要用到的关于线程的公用数据和操作,如下:

JNIEXPORT void JNICALL Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}
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},
};

Thread.java来源
http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/a049121b193b/src/share/classes/java/lang/Thread.java

找到start0对应调用JVM_StartThread,调用JVM_StartThread,抽取核心实现如下:

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_StartThread");
      //省略
      native_thread = new JavaThread(&thread_entry, sz);
      //省略
    }
  }

JVM_StartThread创建步骤:

1.申请一个锁 创建一个JavaThread对象如果有异常情况,抛出异常
2.对第二步的JavaThread类,做一个准备操作:thread.cpp$JavaThread::prepare
3.调用Thread::start方法,让一条线程开始运行

jvm.cpp代码来源
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/tip/src/share/vm/prims/jvm.cpp

JVM_StartThread中创建了一个JavaThread对象,
抽取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
{
 
  os::ThreadType thr_type = os::java_thread;
  thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
                                                     os::java_thread;
  os::create_thread(this, thr_type, stack_sz);

}

thread.cpp代码来源
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/cf85f331361b/src/share/vm/runtime/thread.cpp#l1566

可以看到JavaThread里面创建了OSThread,OSThread是一个平台相关线程,OSThread由JavaThread对象创建并进行管理。在OSThread创建的过程中,会通过pthread方法来创建一个真正意义上的底层级线程。

1.3.3 运行线程

pthread.create新线程创建后就会从thread_native_entry()开始运行,thread_native_entry()中调用了thread->run() ,run()里面调用thread_main_inner()>entry_point()(this, this),entry_point()返回的其实就是在 new JavaThread(&thread_entry, sz) 时传入的thread_entry。这里就相当于调用了thread_entry(this,this)。thread_entry定义在jvm.cpp中:


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);
}

jvm.cpp代码来源
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/tip/src/share/vm/prims/jvm.cpp

上面的文字可能很流水,就是大概描述跳转方向,大家可以参考着跳。核心的是上面代码片段中的JavaCall,这个方法就是调用Java线程对象的run()方法,就跑了。

以上就是我们一个线程怎么启动运行的过程。

1.4 Thread理解

相信通过上面对Thread的认识讲解,大家多多少少都能大概知道线程他是什么,他是做什么的,他是怎么做的及其相关原理,下一章将在Thread理解的基础上对ThreadGroup进行学习。

下一篇:Java线程基础-认识并区分Thread ThreadGroup ThreadLocal ThreadGroupContext(二)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值