线程创建和Thread类

创建一个线程的方法

创建一个线程的方法,有非常多种:

  • 继承Thread类,重写run方法。

  • 实现Runnable接口,实现run方法,然后将Runnable实例传递给Thread构造器。

  • 实现Callable接口,结合FutureTaskThread类(这是对Runnable的功能增强,用于获取返回值)。

继承Thread类

创建一个子类继承Thread类,并且重新run方法

csharp 复制代码
        Thread thread=new Thread(){
            @Override
            public void run() {
                while(true){
                    System.out.println("线程执行中...");
                }
            }
        };

实现Runnable接口

通过实现Runnable接口,重写run方法

csharp 复制代码
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("线程执行中...");
                }

            }
        };
        Thread thread=new Thread(runnable);

实现Callable接口,并封装在FutureTask中,再放入Thread

ini 复制代码
        Callable<String> callable=new Callable<>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(2000);
                return "hello,JUC";
            }
        };
        FutureTask<String> task=new FutureTask<String>(callable);
        Thread thread=new Thread(task);
        thread.start();
        String s = task.get();
        System.out.println(s);

Thread源码解析

三种创建线程的相同点

现在来看看Thread的背后做了什么事。

typescript 复制代码
public class Thread implements Runnable {
    private Runnable target;
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
}

从上述简化的代码来看,Thread本质也是一个Runnable,并且还持有一个Runnable对象。

因此上面的几种方法都有了解释:

  1. 第一种继承Thread,直接覆写run方法的逻辑,不再使用target
  2. 第二种传入一个target,执行target中的run方法
  3. 第三种的本质也是第二种

线程启动的过程

以下是start的源码

csharp 复制代码
public synchronized void start() {

        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {

            }b
        }
    }

start方法被synchronized修饰,确保在多线程环境下,检查线程状态和启动过程是原子的,防止一个线程对象被并发启动多次。

threadStatus为0时,代表着是NEW状态,此时线程对象创建了,但是没有启动,如果threadStatus不为0,说明线程已经启动了。

通过启动加锁与检查线程状态,保证了线程不可重复启动的特性。

从代码中并没有看到run方法被调用的语句,因为真正的启动在start0

相关推荐
cheems9527几秒前
[SpringMVC] Spring MVC 留言板开发实战
java·spring·mvc
BioRunYiXue2 分钟前
AlphaGenome:DeepMind 新作,基因组学迎来 Alpha 时刻
java·linux·运维·网络·数据库·人工智能·eclipse
whatever who cares7 分钟前
android中,全局管理数据/固定数据要不要放一起?
android·java·开发语言
C1829818257513 分钟前
AI idea 集成claude code插件
java·ide·intellij-idea
IT 行者13 分钟前
解决 IntelliJ IDEA 内存占用高的两个优化策略:GPU 渲染与虚拟内存配置
java·ide·intellij-idea·ai编程
Aric_Jones15 分钟前
从实战理解异步、并发并行与GIL:FastAPI vs SpringBoot
java·spring boot·fastapi
云烟成雨TD19 分钟前
Spring AI 1.x 系列【27】Chat Memory API:让 LLM 拥有上下文记忆能力
java·人工智能·spring
渔民小镇20 分钟前
一次编写到处对接 —— 为 Godot/Unity/React 生成统一交互接口
java·分布式·游戏·unity·godot
路ZP21 分钟前
放大镜下拉框
java·数据库·sql
愈努力俞幸运24 分钟前
docker入门,容器,镜像
java·分布式·docker