线程相关复习
- 什么是进程,什么是线程
进程: 程序一次执行, 系统分配和调度的资源单位,每一个进程都有他自己的内存空间和系统资源,一下程序运行需要一个进程
线程: 在同一个程序内可以运行一个或多个任务,每个任务我们可以看为是一个线程,也就是一个进程中会有一个或多个线程
从操作系统层面去看整体是: 多进程运行,允许多个任务同时指向,每个进程中以多线程方式运行(多核时多线程,单核时通过资源调度纳秒级,实际还是单线程), 允许进程和线程之间共享资源,这样就需要提供协调机制,防止进程线程之间冲突
- 管程: 上面说到进程与线程之间共享资源,但是要防止冲突,例如数据安全问题,而管程就相当于这个协调者,Monitor(监视器),也可以说是我们平时说的锁,Monitor是一种同步机制,保证同一时间内只有一个线程访问某个数据和代码,举例: JVM中基于进入和退出监视器对象来实现的synchronized
- java 开启一个线程
new Thread(() -> {
},Thread.currentThread().getName()).start();
- java中通过start方法启动一个线程,查看start源码发现内部实际调用的是native方法start0
- 下载openjdk源码, 在openjdk中JNI的写法与java是一一对应的,例如Thread.java就对应openjdk中的Thread.c
- start0也就对应JVM_StartThread,这个源代码在jvm.h,中可以找到声明,在jvm.cpp中找到实现(.cpp是c++文件后缀,有点像.java)
- 再往下查看JVM_StartThread中实际调用的是操作系统os的开启一个线程命令
java 线程分类
- java中线程分为用户线程跟守护线程,举个例子例如启动main方法后,至少有main主线程与GC守护线程两个线程
- 示例代码
- 运行下方示例代码会发现:main方法属于用户线程,main方法中new出来的线程也是用户线程
- main方法停止后,不会影响内部new出来的用户线程
- 当执行setDaemon(true)方法传递true时,会将线程设置为守护线程,注意点设置守护线程需要放到start方法前
- 守护线程跟随主线程消亡,而消亡
public class JucTest {
public static void main(String[] args) {
//开启一个线程
Thread a = new Thread(()->{
//判断当前线程是否是守护线程 true: 守护线程, false: 用户线程
boolean b = Thread.currentThread().isDaemon();
//死循环防止当前线程停止
while (true) {
}
},Thread.currentThread().getName());
//设置a线程为守护线程
a.setDaemon(true);
a.start();
System.out.println("Main 主线程 停止");
}
}