核心概念

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

  1. 继承Thread
  2. 实现Runnable接口
  3. 实现Callable接口(配合FutureTask
  4. 使用线程池(推荐)

详细解析

1. 继承Thread类

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程执行:" + Thread.currentThread().getName());
    }
}

// 使用
MyThread thread = new MyThread();
thread.start();

缺点:Java单继承限制,扩展性差。

2. 实现Runnable接口

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程执行:" + Thread.currentThread().getName());
    }
}

// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();

// 或使用Lambda(推荐)
new Thread(() -> System.out.println("执行任务")).start();

优点:避免单继承限制,代码解耦,更符合面向对象思想。

3. 实现Callable接口

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        return "任务执行结果";
    }
}

// 使用
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
new Thread(futureTask).start();

// 获取返回值(阻塞)
String result = futureTask.get();

优点

  • 有返回值
  • 可以抛出异常
  • 支持泛型

4. 使用线程池(推荐)

ExecutorService executor = Executors.newFixedThreadPool(10);

// 提交Runnable
executor.execute(() -> System.out.println("执行任务"));

// 提交Callable
Future<String> future = executor.submit(() -> {
    return "任务结果";
});

executor.shutdown();

优点

  • 复用线程,减少创建销毁开销
  • 统一管理线程资源
  • 提供队列缓冲和拒绝策略
  • 生产环境首选方案

性能与最佳实践

线程安全考量

  • 多个线程共享同一个Runnable实例时,注意成员变量的线程安全
  • 优先使用局部变量或ThreadLocal

生产环境建议

// 避免使用Executors工具类,手动创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10,                      // 核心线程数
    20,                      // 最大线程数
    60L,                     // 空闲线程存活时间
    TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100),  // 任务队列
    new ThreadFactoryBuilder()
        .setNameFormat("business-pool-%d")
        .build(),
    new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略
);

答题总结

面试标准答案

  • 继承Thread:简单但受单继承限制
  • 实现Runnable:解耦灵活,无返回值
  • 实现Callable:有返回值,可抛异常
  • 线程池:生产首选,资源复用,统一管理

关键点:本质上只有一种创建线程的方式——new Thread(),其他都是在定义线程执行的任务。RunnableCallable是任务抽象,线程池是管理方式。

推荐方案:生产环境统一使用自定义线程池 + Runnable/Callable