线程基础知识复习
1|0并发相关Java包
- 涉及到的包内容
- java.util.concurrent
- java.util.concurrent.atomic
- java.util.concurrent.locks
JUC包创始人 Doug Lea
2|0start线程解读
- 初始程序
由以上代码可知:
1、Thread类在被加载的时候,首先会执行静态代码块,调用本地方法registerNatives去注册所有的本地方法。
2、在new Thread的过程中会执行如下核心逻辑:
1)设置线程的名字。
2)获取调用线程是否是守护线程及优先级并设置到当前线程。
3)设置线程的执行体到线程对象中。
4)最后重新设置优先级
3、然后执行start方法执行线程体,调用本地方法start0执行线程体。
综上所述,我们可以清楚知道,本地线程的创建和java线程与本地线程的映射的逻辑是在native层完成的。据此我们主要分析两个native方法的执行逻辑:
1)registerNatives :所有本地方法的注册。
2)start0 :创建本地线程并执行java线程体。
native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。
native调用了本地方法,我们可以通过下载官网OpenJDK查看其源码
2|1Native层的实现
native层由jdk实现,据此我们需要翻越jdk的源码,我用的openjdk1.8源码。
那么在java层线程对应的实现在 Thread.java,同样在natvie层叫Thread.c
openjdk/jdk/src/share/native/java/lang/Thread.c
由以上代码可以看到所有Thread.java中的本地方法都在这里注册。好,接下来我们看start0的本地实现JVM_StartThread
openjdk/hotspot/src/share/vm/prims/jvm.cpp
继续追进 new JavaThread(&thread_entry, sz);
/home/wangzijie/code2/openjdk/hotspot/src/share/vm/runtime/thread.cpp
继续追追进去 os::create_thread(this, thr_type, stack_sz); 我们选择linux的线程实现
openjdk/hotspot/src/os/linux/vm/os_linux.cpp
继续追进 java_start
openjdk/hotspot/src/os/linux/vm/os_linux.cpp
好了,到这里java线程的创建与执行基本已经分析完了,但是还差一点,那就是上面的代码的阻塞何时解除?因为解除阻塞以后才能执行thread->run,进而执行Runnable的的实现,真正执行我们的java代码。要回答这个问题我们需要往前看,还记得本地线程创建的入口吗
openjdk/hotspot/src/share/vm/prims/jvm.cpp
这里的 Thread::start(native_thread); 我们追进去看一下
openjdk/hotspot/src/share/vm/runtime/thread.cpp
这里的Thread::start会解除线程的阻塞进而执行run方法
3|0Java多线程相关概念
3|11把锁
3|22个并(并发和并行)
- 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行(需要多核CPU)
- 并发是指两个任务都请求运行,而处理器只能接收一个任务,就是把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行(12306抢票的案例)
3|33个程(进程 线程 管程)
进程
系统中运行的一个应用程序就是一个进程,每一个进程都有它自己的内存空间和系统资源。
线程
也被称为轻量级进程,在同一个进程内基本会有1一个或多个线程,是大多数操作系统进行调度的基本单元。
管程
Monitor(监视器),也就是我们平时说的锁
Monitor其实是一种同步机制,他的义务是保证(同一时间)只有一个线程可以访问被保护的数据和代码。
JVM中同步是基于进入和退出监视器对象(Monitor,管程对象)来实现的,每个对象实例都会有一个Monitor对象,
Monitor对象会和Java对象一同创建并销毁,它底层是由C++语言来实现的。
进程VS线程
进程是…,线程是…,进程和线程的最大不同在于进程基本上是独立的,而线程不一定,线程共享方法区和堆,线程私有****栈、本地方法栈和程序计数器
4|0用户线程和守护线程
Java线程分为用户线程和守护线程
- 线程的daemon属性为
- true表示是守护线程
- false表示是用户线程
[
](https://blog.csdn.net/dolpin_ink/article/details/125082584)
4|1用户线程
是系统的工作线程,它会完成这个程序需要完成的业务操作
4|2守护线程
是一种特殊的线程,为其他线程服务的,在后台默默地完成一些系统性的服务,比如垃圾回收线程。
4|3总结
两种情况
- 未加t1.setDaemon(true);,默认是用户线程,他会继续运行,所以灯亮着
- 加了t1.setDaemon(true);是守护线程,当用户线程main方法结束后自动退出了
-
守护线程作为一个服务线程,没有服务对象就没有必要继续运行了,如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了,系统可退出了。假如当系统只剩下守护线程的时候,java虚拟机会自动退出。
-
setDaemon(true)方法必须在start()之前设置,否则报IIIegalThreadStateException异常
__EOF__

本文链接:https://www.cnblogs.com/jinronga/p/16485558.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix