目录
一、Java程序的运行
1.启动过程
(1)Java程序启动时,操作系统 会为此Java程序 创建一个JVM进程来运行
(2)JVM进程 创建并启动 主线程main ,从主线程的入口方法main() 开始执行
2.线程任务
每个线程启动后 以执行完入口方法为准地 ++自动调用++去执行run方法
- thread.start () 启动->调用 thread.run()
二、线程的创建
创建线程时,原生线程对象的 入口方法run() 是选择性空逻辑,需要多态地 重新自实现出一个run()方法 并执行它 ,无法在Thread类源码那边 直接修改成自己的run逻辑,得在 往下扩展的 Thread子类 或Runnable实现类 中 重写自实现run
链接:重写详解
1.Thread子类重写

创建 Thread类的 子类线程后,在直接子类线程 或转型父类线程 都能执行 自实现的run方法
1.1子类线程直接执行
子类线程 继承可调用 父类的start(),在子类线程里 重写自实现出run方法后,start启动子类线程 便调用执行子类线程里面 自实现的run方法了(父子相同的run方法,子类优先调用)
1.2父类线程重写执行
子类线程 赋值向上转型 成父类线程 后,父类线程 启动调用 也不管target是否为空 会重写 向下转 回执行 子类线程自实现的run方法
1.2.1向上转型
子类线程 继承原生线程 自实现出run方法逻辑后,其实就可++直接启动子类线程 直接调用执行 子类线程已自实现的run逻辑++ 了,但常常将子类线程 赋值向上转型成 统一的父类原生线程 ,启动原生线程来调用run 再往下重写转回执行 子类线程重写的自实现run
意义
父类 可以无限制地 向下继承 出 千姿百态的子类 、创建出 各种各样的子类实例
将子类实例 全部各自 赋值向上转型成 统一父类的实例,各种各样的子类实例 就可以靠赋值对应关系 全部统一用简单的父类模式又对应各自效果地 简单统一又多态效果地管理了
1.2.2匿名类
匿名类 省去跳过 类的单独创建,使用匿名方式 快速一次性创建 ++继承子类++ 、++实现接口++ 的 扩展类实例
- 匿名类实现只有一个抽象方法的接口 还可以化简成Lambda表达式 来创建实例
链接:匿名类详解
链接: Lambda表达式详解
场景
(1)向上转型
将子类实例 赋值向上转型成 用父类实例管理后,父类调用使用时 具体重写转化到哪个子类、子类方法具体如何实现的细节 都可以不用知道 ,只需要了解使用 转成的简单父类层面 ,++以后都不会主动用到子类的++
(2)临时针对
继承的子类的 类类型 就是只使用一次 来临时创建子类实例 只针对这种情况使用的,++以后再也不会有 重复使用此类的需求++
java
class ChildThread extends Thread{
@Override
public void run() {
//run自实现内容
}
}
class Test1 {
public static void main(String[] args) {
//1.用定义的Thread子类ChildThread 实例创建
Thread thread1 = new ChildThread();
thread1.start();
//2.用扩展继承Thread的匿名子类 实例创建
Thread thread2 = new Thread() {
@Override
public void run() {
//run自实现内容
}
};
thread2.start();
}
}
2.Runnable实现类重写

可以创建Thread类 原生线程,传入 里面已重写自实现run方法的 Runnable接口实现类实例 ,赋值向上转型成 Runnable接口类型的 target变量 ,start启动Thread类线程时 调用原生线程的run方法,target不为空 选择调用 已向上转型target接口变量的 run方法,即会向下重写 转 到执行 Runnable实现类里面 自实现的run方法
(原生父类Thread的构造方法 里面都还可额外传入 String字符串 作为线程的名字)
java
class ChildRunnable implements Runnable{
@Override
public void run() {
//run自实现内容
}
}
class Test2 {
public static void main(String[] args) {
//1.用定义的Runnable实现类ChildRunnable 实例创建 Runnable的实现类实例
Thread thread1 = new Thread(new ChildRunnable());
thread1.start();
//2.1用扩展实现Runnable接口的匿名子类 实例创建
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
//run自实现内容
}
});
//2.2Lambda表达式化简2.1
Thread thread3 = new Thread(()->{
//run自实现内容
});
}
}
三、线程的属性
|--------|-----------------|
| 属性 | 获取方法 |
| ID | getId() |
| 名称 | getName() |
| 状态 | getState() |
| 优先级 | getPriority() |
| 是否后台线程 | isDaemon() |
| 是否存活 | isAlive() |
| 是否被中断 | isInterrupted() |
[线程的属性]
链接:线程详解
1.优先级
操作系统 按由系统调度器具体实现决定的 即使有一定优先级分配 但也无法固定概率的 随机顺序 对已启动线程进行调度
2.存活
run执行结束,操作系统内核里的该线程 也就销毁死亡 了,Thread对象的生命周期 比对应线程的生命 更长一些,可以获取 所对应线程 是否存活的信息
3.前台线程
前台线程是否还有存活 决定整个++进程++的结束 ,线程默认是前台线程