Skip to content

创建线程的方式有几种?区别是什么?

答案

Java 中创建线程的方式主要有 4 种

  • 继承 Thread:直接继承,重写 run(),简单但不灵活。
  • 实现 Runnable:接口实现,解耦任务和线程,无返回值。
  • 实现 Callable:接口实现,支持返回值和异常处理。
  • 线程池:复用线程,高并发下高效管理。

具体区别

1. 实现方式

  • Thread:继承类,重写 run(),创建即线程对象。
    • 示例:new MyThread().start()。
  • Runnable:实现接口,传入 Thread 构造器。
    • 示例:new Thread(new MyRunnable()).start()。
  • Callable:实现接口,结合 FutureTask 包装。
    • 示例:new Thread(new FutureTask<>(new MyCallable())).start()。
  • 线程池:通过 ExecutorService 提交任务。
    • 示例:executor.submit(runnable)。

2. 功能支持

  • Thread:仅执行任务,无返回值。
  • Runnable:仅执行任务,无返回值。
  • Callable:支持返回值(通过 Future.get() 获取)和异常抛出。
  • 线程池:支持任务管理(提交、取消)、返回值(若用 Callable)。

3. 灵活性

  • Thread:耦合高,不能继承其他类。
  • Runnable:解耦任务和线程,可继承其他类。
  • Callable:功能更强,但需额外 FutureTask。
  • 线程池:高度灵活,动态调整线程数。

4. 性能与资源

  • Thread:每次创建新线程,开销大(约 1MB 栈内存)。
  • Runnable:仍需手动创建线程,开销同上。
  • Callable:同上,但逻辑复杂。
  • 线程池:复用线程,减少创建/销毁开销,适合高并发。

5. 使用场景

  • Thread:简单单次任务。
  • Runnable:通用任务,推荐基础方式。
  • Callable:需要结果或异常处理的异步任务。
  • 线程池:高并发、批量任务(如 Web 服务)。

延伸与面试角度

  • 其他方式?
    • 严格来说,只有 Thread 和 Runnable 是基础方式,Callable 和线程池是扩展。
  • 选择依据
    • Thread:简单任务,少用。
    • Runnable:通用,解耦任务和线程。
    • Callable:需要返回值或异常。
    • 线程池:高并发,资源复用。
  • 优缺点
    • Thread:耦合高,每次新建开销大。
    • Runnable:灵活,但无返回值。
    • Callable:功能强,但复杂。
    • 线程池:性能优,但需管理。
  • 实际应用
    • Spring 用线程池(TaskExecutor)异步处理。
    • Fork/Join 框架基于线程池。
  • 面试点
    • 问“区别”时,提继承 vs 接口、返回值。
    • 问“线程池优势”时,提复用和资源控制。
  • Callable vs Runnable?
    • Callable 有返回值,Runnable 无,适合不同需求。
  • 线程池优势?
    • 复用线程,控制并发数,避免线程爆炸。
  • 为什么 Runnable 优于 Thread?
    • 解耦任务逻辑和线程控制,符合面向接口编程。