线程创建和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 小时前
ApacheCommons——commons-pool2(高性能通用对象池框架)
java·开发语言·apache
xcl09256 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌6 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天6 小时前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star6 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
今天AI了吗7 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
许彰午7 小时前
27-AuthService登录链路
java·低代码·架构
泡海椒8 小时前
JQuick-Curl 性能分析:并发场景下的性能表现与调优,第三方接口调用不只要快写也要稳跑
java·开发语言·okhttp
Rain的Java大神之路9 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
自动化监测Learner9 小时前
Navicat Premium 17 中文版安装教程(2026最新版)
java·linux·数据库