Skip to content

线程创建、启动、停止

一、线程创建

是什么?
线程是程序执行的最小单位,线程创建指在Java中生成一个可执行的任务单元。JDK8后主要支持三种方式:

  1. 继承 Thread
  2. 实现 Runnable 接口
  3. 实现 Callable 接口(JDK5+,配合Future/FutureTask)

解决什么问题

  • 实现并发执行,提高CPU利用率
  • 避免主线程阻塞(如耗时I/O操作)
  • 充分利用多核处理器资源

核心方法

java
// 方式1:继承Thread
class MyThread extends Thread {
    public void run() { /* 任务逻辑 */ }
}

// 方式2:实现Runnable
class MyRunnable implements  {
    public void run() { /* 任务逻辑 */ }
}

// 方式3:实现Callable(可返回结果)
class MyCallable implements Callable<String> {
    public String call() { return "结果"; }
}

应用场景

  • 后台任务处理(如日志写入)
  • 异步计算(如并行数据处理)
  • 实时响应(如GUI事件处理)

Java示例(JDK8+)

java
// Lambda简化Runnable(JDK8+)
Thread lambdaThread = new Thread(() -> {
    System.out.println("Lambda线程运行中");
});

// CompletableFuture异步任务(JDK8+)
CompletableFuture.runAsync(() -> {
    System.out.println("CompletableFuture线程");
});

重要注意事项

  1. 优先选择 Runnable/Callable(避免Java单继承限制)
  2. 线程创建开销大,高并发场景推荐用线程池
  3. JDK8的Lambda可简化匿名内部类写法

二、线程启动

是什么?
通过调用 start() 方法使线程进入就绪状态,等待JVM调度执行。

解决什么问题

  • 激活线程执行(区别于直接调用 run()
  • 由操作系统管理线程调度
  • 实现真正的并发执行

核心方法

java
thread.start(); // 启动线程(非阻塞)

应用场景

  • 需要并发执行的任何场景
  • 定时任务触发
  • 事件驱动编程

Java示例

java
// 正确启动方式
MyThread thread = new MyThread();
thread.start(); // JVM自动调用run()

// 错误方式(不会启动新线程)
thread.run(); // 仅在当前线程执行

重要注意事项

  1. start() 只能调用一次,重复调用抛 IllegalThreadStateException
  2. 启动顺序 ≠ 执行顺序(由线程调度器决定)
  3. JDK19虚拟线程(预览特性)启动方式相同

三、线程停止

是什么?
安全终止线程执行的过程。Java不推荐直接使用废弃的 stop() 方法。

解决什么问题

  • 避免资源未释放(如文件句柄、数据库连接)
  • 防止数据不一致(突然终止导致状态异常)
  • 实现优雅退出

核心方法

java
// 协作式中断(推荐)
thread.interrupt(); // 设置中断标志

// 标志位停止(需volatile保证可见性)
private volatile boolean stopped = false;

应用场景

  • 用户取消长时间操作
  • 服务关闭时停止工作线程
  • 超时任务终止

Java示例

java
// 方法1:检查中断标志
class SafeThread extends  {
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            // 执行任务
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // 捕获中断异常后需重置标志
                Thread.currentThread().interrupt(); 
                break;
            }
        }
    }
}

// 方法2:使用标志位
class FlagThread extends  {
    private volatile boolean stopped = false;
    
    void stopThread() { stopped = true; }
    
    public void run() {
        while (!stopped) {
            // 执行任务
        }
    }
}

重要注意事项

  1. 禁止使用 stop()/suspend()/resume()(已废弃,会导致死锁/数据损坏)
  2. 阻塞方法(如 sleep()/wait())会抛 InterruptedException
  3. 捕获中断异常后必须重置中断标志(调用 interrupt()
  4. JDK7+的 try-with-resources 可配合自动关闭资源

区别对比

特性Thread类继承Runnable接口Callable接口
返回值有(通过Future获取)
异常处理只能在run()内部处理同左可向外抛出异常
单继承限制受限制不受限不受限
JDK8+Lambda支持不支持支持支持

总结

  1. 创建:优先选 Runnable/Callable,JDK8+可用Lambda简化
  2. 启动:必须通过 start(),直接调用 run() 不会启动新线程
  3. 停止
    • 使用协作式中断(interrupt() + 状态检查)
    • 阻塞方法需捕获 InterruptedException
    • 资源释放放在 finally 块中
  4. 最佳实践
    java
    // JDK5+线程池示例
    ExecutorService pool = Executors.newFixedThreadPool(4);
    pool.submit(() -> {
        while (!Thread.interrupted()) {
            // 任务逻辑
        }
    });
    pool.shutdown(); // 优雅关闭
  5. 新特性
    • JDK19虚拟线程(轻量级线程,高并发场景)
    • CompletableFuture(JDK8+异步编程)
    • ForkJoinPool(分治任务处理)