线程创建和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

相关推荐
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19947 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
噢,我明白了8 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品8 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘8 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记9 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端