Java线程创建与运行全解析

目录

一、Java程序的运行

1.启动过程

2.线程任务

二、线程的创建

1.Thread子类重写

1.1子类线程直接执行

1.2父类线程重写执行

1.2.1向上转型

意义

1.2.2匿名类

场景

(1)向上转型

(2)临时针对

2.Runnable实现类重写

三、线程的属性

1.优先级

2.存活

3.前台线程


一、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.前台线程

前台线程是否还有存活 决定整个++进程++的结束 ,线程默认是前台线程

相关推荐
Peregrine914 分钟前
C++ - > 类和对象
java·c++·算法
一条泥憨鱼16 分钟前
【从0开始学习计算机网络】| ARP 协议:地址解析,ARP 欺骗,链路层寻址
网络·后端·学习·计算机网络
余醉 | dtminer18 分钟前
56%的保护效应藏在乳腺密度里:Nat Commun 高分中介孟德尔随机化全 R 管线拆解(附核心图)
开发语言·r语言·孟德尔随机化
2501_9339232521 分钟前
SpringCloud组件:Eureka服务注册与发现
java·开发语言·后端·spring cloud·eureka
Wang's Blog22 分钟前
Java 中间件之 RabbitMQ 快速入门: SpringAMQP 消息转换器
java·中间件·java-rabbitmq
leikooo25 分钟前
ARTS 1011: 双堆动态对顶求中位数、IPC 注入与空密码串联接管账户与程序从不做决策
后端
合尘猫31 分钟前
AI 项目上线就停:一次事件循环阻塞的完整排查过程
人工智能·后端·python
染指111039 分钟前
142.Agent-多Agent框架-通过Skills实现多Agent
开发语言·人工智能·python·langchain·agents
Re_zero1 小时前
一次 SSE 断流排查:PrintWriter 吞掉了我的 IOException
java·后端
HY小宝F1 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http