目录
1.线程和方法调用栈的关系:
每个线程都有自己独立的调用栈
这就是调试器中看到的方法调用栈,每一行都是一个栈帧(frame),
保存的就是运行方法时的临时数据,对于我们来说最主要的就是局部变量
由于每个线程都是独立的执行流,A在调用过哪些方法和B线程根本就没关系
表现为每个线程都有自己独立的栈
调用的是同一个方法:说明执行的是同一批指令
栈不同(帧不同):说明要执行指令时,要处理的数据是不同的
鼠标右击断电,就可以进行设置:
2.线程中最常见的属性:
1.id 本进程(JVM进程)内部分配的唯一id,只能get,不能set
2.name为了给开发者看的,JVM并不需要这个属性
默认情况下,如果没有给过名字,线程名字遵循Thread-0、Thread-1....
可以设置,也可以get
可以通过setName()设置,也可以通过Thread()构造方法设置
public class Main3 {
static class MyThread extends Thread{
// public MyThread(){
// //构造方法报错的原因可能是拼写错误
// setName("我是门小静");
// }
//thread类本身提供的改名方法
public MyThread(){
super("我是小门");
}
@Override
public void run() {
System.out.println(this.getName());
}
public static void main(String[] args) {
Thread thread = Thread.currentThread();//当前线程
System.out.println(thread.getName());
MyThread t1 = new MyThread();
t1.start();
MyThread t2 = new MyThread();
t2.start();
MyThread t3 = new MyThread();
t3.start();
}
}
}
id就是一个线程的身份证号(出生时被分配,无法修改,不能重复),
name就是一个线程的名字(可以重复,可以被修改)
t1 t2 t3这三个线程是由主线程执行创造出来的线程,所以取名“子线程”,创造上油浮子关系,但被调度时地位平等!
MyThread类只是给线程去执行的程序,是一个静态内容
3.在java代码中看到的线程状态
(只能获取,不能设置,状态变更是jvm的控制的)
县城可以Get和set自己的优先级
优先级的设置,只是给jvm一些建议,不能强制让哪个线程先被调度
(1)理论中的状态
(2)Java代码中实际看到的状态
4.前台线程和后台线程(daemon精灵线程)
后台线程一般做一些支持工作的线程,前台线程一般是做一些有交互工作的。
比如:写了一个音乐播放器
1.线程响应用户点击动作(前台)
2.线程去网络上下载歌曲(后台)
JVM进程什么时候才能退出:所有的前台线程都退出了,JVM进程就退出了
1.必须要求所有前台都退出,和主线程没关系
2.和后台线程没关系,即使后台还在工作,也正常退出
总结:线程的场景属性(我们都是通过Thread对象进行操作)
id(get) 、name(get、set)
状态(get)、优先级(get、set)
前后台线程(get、set)
相关代码请参照我的码云thread: 关于线程的一些代码以及知识点
JDK中自带的观察线程的工具:jconsole.exe(可以看到Jvm运行时的一些相关情况,比如:内存、类加载情况、线程情况)
注意:检测线程状态,需要在程序运行时进行
jconsole具体操作过程:
Thread下的几个常见静态方法:
1.Thread.sleep(...) 让线程休眠...毫秒
2.TimeUnit.SECONDS.sleep(1) == Thread.sleep(1000)
提供了很多时间单位
什么是休眠?
从线程的中台的角度,调用sleep(?),就是让当前线程从“运行状态”变成“阻塞状态”
等待某个条件:要求时间过去多久之后
时间真的过去那么久之后,线程从阻塞变到就绪状态
当线程被调用器选中时,开始截止之前的指令执行,表现为sleep之后的语句执行
外部表现让线程休眠一段时间
3.Thread.currentThread();
Thread引用,执行一个线程对象,执行的就是在哪个线程中调用的该方法,返回哪个对象。