group.threadStartFailed(this);}} catch (Throwable ignore) {}
}

}


*   线程启动方法 start(),在它的方法英文注释中已经把核心内容描述出来。Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread. 这段话的意思是:由 JVM 调用此线程的 run 方法,使线程开始执行。其实这就是一个 JVM 的回调过程,下文源码分析中会讲到*   另外 start() 是一个 synchronized 方法,但为了避免多次调用,在方法中会由线程状态判断。threadStatus != 0。*   group.add(this),是把当前线程加入到线程组,ThreadGroup。*   start0(),是一个本地方法,通过 JNI 方式调用执行。这一步的操作才是启动线程的核心步骤。### 2.2 start0() 本地方法

// 本地方法 start0
private native void start0();

// 注册本地方法
public class Thread implements Runnable {
/* Make sure registerNatives is the first thing does. */
private static native void registerNatives();
static {
registerNatives();
}
// …
}


*   start0(),是一个本地方法,用于启动线程。*   registerNatives(),这个方法是用于注册线程执行过程中需要的一些本地方法,比如:start0、isAlive、yield、sleep、interrupt0等。registerNatives,本地方法定义在 Thread.c 中,以下是定义的核心源码:

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},
{“interrupt0”, “()V”, (void *)&JVM_Interrupt},
{“holdsLock”, “(” OBJ “)Z”, (void *)&JVM_HoldsLock},
{“getThreads”, “()[” THD, (void *)&JVM_GetAllThreads},
{“dumpThreads”, “([” THD “)[[” STE, (void *)&JVM_DumpThreads},
{“setNativeName”, “(” STR “)V”, (void *)&JVM_SetNativeThreadName},
};


*   从定义中可以看到,start0 方法会执行 &JVM_StartThread 方法,最终由 JVM 层面启动线程。### 3\. JVM 创建线程### 3.1 JVM_StartThread

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
JVMWrapper(“JVM_StartThread”);
JavaThread *native_thread = NULL;

// 创建线程
native_thread = new JavaThread(&thread_entry, sz);
// 启动线程
Thread::start(native_thread);

JVM_END


*   这部分代码比较多,但核心内容主要是创建线程和启动线程,另外 &thread_entry 也是一个方法,如下:thread_entry,线程入口

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

重点,在创建线程引入这个线程入口的方法时,thread_entry 中包括了 Java 的回调函数 JavaCalls::call_virtual。这个回调函数会由 JVM 调用。vmSymbols::run_method_name(),就是那个被回调的方法,源码如下:

#define VM_SYMBOLS_DO(template, do_alias)
template(run_method_name, “run”)


*   这个 run 就是我们的 Java 程序中会被调用的 run 方法。接下来我们继续按照代码执行链路,寻找到这个被回调的方法在什么时候调用的。### 3.2 JavaThread

native_thread = new JavaThread(&thread_entry, sz);


接下来,我们继续看 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
{
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;
os::create_thread(this, thr_type, stack_sz);
}


*   ThreadFunction entry_point,就是我们上面的 thread_entry 方法。*   size_t stack_sz,表示进程中已有的线程个数。*   这两个参数,都会传递给 os::create_thread 方法,用于创建线程使用。### 3.3 os::create_thread众所周知,JVM 是个啥!,所以它的 OS 服务实现,Liunx 还有 Windows 等,都会实现线程的创建逻辑。这有点像适配器模式os_linux -> os::create_thread

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);
// Initial state is ALLOCATED but not INITIALIZED
osthread->set_state(ALLOCATED);

pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* ()(void)) java_start, thread);

return true;
}


*   osthread->set_state(ALLOCATED),初始化已分配的状态,但此时并没有初始化。*   pthread_create,是类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数。*   java_start,重点关注类,是实际创建线程的方法。### 3.4 java_start

static void *java_start(Thread *thread) {

// 线程ID
int pid = os::current_process_id();

// 设置线程
ThreadLocalStorage::set_thread(thread);

// 设置线程状态:INITIALIZED 初始化完成
osthread->set_state(INITIALIZED);

// 唤醒所有线程
sync->notify_all();

// 循环,初始化状态,则一致等待 wait
while (osthread->get_state() == INITIALIZED) {
sync->wait(Mutex::_no_safepoint_check_flag);
}

// 等待唤醒后,执行 run 方法
thread->run();

return 0;
}


*   JVM 设置线程状态,INITIALIZED 初始化完成。*   sync->notify_all(),唤醒所有线程。*   osthread->get_state() == INITIALIZED,while 循环等待*   thread->run(),是等待线程唤醒后,也就是状态变更后,才能执行到。这在我们的线程执行UML图中,也有所体现### 4\. JVM 启动线程

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
JVMWrapper(“JVM_StartThread”);
JavaThread *native_thread = NULL;

// 创建线程
native_thread = new JavaThread(&thread_entry, sz);
// 启动线程
Thread::start(native_thread);

JVM_END


*   JVM_StartThread 中有两步,创建(new JavaThread)、启动(Thread::start)。创建的过程聊完了,接下来我们聊启动。### 4.1 Thread::start

void Thread::start(Thread* thread) {
trace(“start”, thread);

if (!DisableStartThread) {
if (thread->is_Java_thread()) {
java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
java_lang_Thread::RUNNABLE);
}
// 不同的 OS 会有不同的启动代码逻辑
os::start_thread(thread);
}
}


*   如果没有禁用线程 DisableStartThread 并且是 Java 线程 thread->is_Java_thread(),那么设置线程状态为 RUNNABLE。*   os::start_thread(thread),调用线程启动方法。不同的 OS 会有不同的启动代码逻辑### 4.2 os::start_thread(thread)

void os::start_thread(Thread* thread) {
// guard suspend/resume

一线互联网大厂Java核心面试题库

va_thread(),那么设置线程状态为 RUNNABLE。

  • os::start_thread(thread),调用线程启动方法。不同的 OS 会有不同的启动代码逻辑

4.2 os::start_thread(thread)


void os::start_thread(Thread* thread) {// guard suspend/resume## 一线互联网大厂Java核心面试题库[外链图片转存中...(img-s9LBQXTB-1628592152406)]正逢面试跳槽季,给大家整理了大厂问到的一些面试真题,由于文章长度限制,只给大家展示了部分题目,更多Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等...已整理上传在**我的[腾讯文档【一线互联网大厂Java核心面试题库】点击即可领取](https://gitee.com/vip204888/java-p7)**,并会持续更新...感兴趣的朋友可以看看支持一波!

Thread-start()-,它是怎么让线程启动的呢,Java面试问项目相关推荐

  1. 【java】Thread.start 它是怎么让线程启动的呢

    1.概述 转载:面经手册 · 第19篇<Thread.start() ,它是怎么让线程启动的呢?> 可悲可叹,这个问题,6年了,我才第一次知道. 线程启动分析 new Thread(() ...

  2. Java并发编程—Thread类的start()方法是如何启动一个线程的?

    目录 一:Java线程介绍 二:Java线程入口分析 三:Java线程的创建 四:总结 周末抽了点时间,研究了下HotSpot是如何创建Java线程的,顺便总结一下.文中引用的源码里删除很多细节,只保 ...

  3. 【Java 语言】Java 多线程 一 ( 线程基础 : 线程启动 | 线程停止 | 线程暂停 | 线程优先级 | 守护线程)

    一. 线程启动 线程启动 : -- 1. 继承 Thread 运行线程 : 重写 Thread 类的 run 方法, 然后执行该线程; -- 2. 实现 Runnable 接口, 并运行线程; -- ...

  4. java线程 创建与启动_浅析Java中线程的创建和启动

    前言 线程是一个程序内部的顺序控制流.cpu实际上在一个时间点上,只执行一个.只不过我们把cup分成了多个时间片,由于速度很快,我们看起来像是多个线程.就像你的时间分成几片,这样整体看来做事情有规律, ...

  5. java runnable线程锁_多线程 java 同步 、锁 、 synchronized 、 Thread 、 Runnable

    线程 1 线程概述 1.1 什么是线程 v  线程是程序执行的一条路径, 一个进程中可以包含多条线程 v  一个应用程序可以理解成就是一个进程 v  多线程并发执行可以提高程序的效率, 可以同时完成多 ...

  6. python线程暂停_python3线程启动与停止

    转自: https://blog.csdn.net/weixin_38125866/article/details/76795462 https://www.cnblogs.com/lcchuguo/ ...

  7. c++多线程——线程启动

    线程创建 基础版本 需要构造一个std::tread对象,传入参数为任何可调用对象. #include <iostream> #include <thread> using n ...

  8. 怎么判断自己启动的线程是否执行完成 java_Java面试笔记(上)

    面试整体流程(HR 或技术面) 1.请简单的自我介绍 我叫***,工作*年了,先后做过**项目.**项目. 2.请你简单的介绍一下**项目 该系统主要有哪些部分组成,简单介绍项目的整体架构,具体参与某 ...

  9. Thread、Runnable、Callable基本操作线程基本概念

    大家好我是wave,本篇文章给大家介绍一些有关线程的基本概念与线程的一些基本操作 线程与进程 进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位.还存在资源开销.包含关系.内存分 ...

最新文章

  1. python代码大全表解释-python文件及目录操作代码汇总
  2. 第21章:MongoDB-聚合操作--聚合管道--$geoNear
  3. λ-矩阵(初等因子)
  4. hdu 4966 最小树形图
  5. java 使用maven 打包 添加本地lib包
  6. map、forEach与filter实例详解
  7. luoguP3507 [POI2010]GRA 性质 + 动态规划
  8. ExtJS 可视化开发工具大全
  9. win10打印服务器纸规格没有显示,win10系统打印机添加了自定义的纸张却找不到的操作办法...
  10. 千兆网线水晶头的接法
  11. 黄金分割法,你会了吗?
  12. matlab 如何读取二进制、十六进制txt文档
  13. 用于高速网络的实时且可靠的基于异常的入侵检测
  14. 联通光猫后台 192.168.1.1登录
  15. 教你如何拥有好看的CMD界面 如何美化Windows Terminal
  16. 数据采集的方法有哪些
  17. 苹果六电池_苹果官网上架新品,18999元起~
  18. activiti 工作流会签 / 多人审批时若一人通过即可
  19. 一班洽谈框架细化_健全完善组织架构,明确细化职责分工,快速推进项目进展...
  20. 关于富文本kindeditor中上传本地图片成功后获取到的图片路径是相对路径修改为绝对路径...

热门文章

  1. Flutter布局锦囊---验证码倒计时
  2. 冷室压铸机行业调研报告 - 市场现状分析与发展前景预测
  3. 2021年中国车载信息娱乐系统市场趋势报告、技术动态创新及2027年市场预测
  4. 为什么不用mysql做数据仓库hdfs_为什么不建议将RAID用于Hadoop HDFS设置?
  5. Python菜鸟入门:day17编程学习
  6. Python菜鸟入门:day09数据结构
  7. 【历史上的今天】8 月 13 日:Oracle 起诉 Google,Java 版权案正式开启!
  8. “一学就会”微服务的架构模式
  9. 如果NATv6 是个笑话,那么 IPv6 是什么?
  10. 腾讯云区块链产品负责人邵兵:产业区块链刚刚起步,做好基础设施才有可能进入2.0阶段