• Java 中,有三种常用的方法来创建线程:

    1. 继承 Thread
    2. 实现 Runnable 接口
    3. 使用 CallableFuture

    方法一:继承 Thread

    特点:

    • 直接继承 Thread 类并重写 run() 方法。
    • 使用 start() 方法启动线程。

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class MyThread extends Thread {
    @Override
    public void run() {
    System.out.println("线程 " + Thread.currentThread().getName() + " 正在运行");
    }
    }

    public class Main {
    public static void main(String[] args) {
    MyThread t1 = new MyThread();
    MyThread t2 = new MyThread();
    t1.start();
    t2.start();
    }
    }

    优点: 简单直观,直接创建线程对象。
    缺点: Java 不支持多继承,继承 Thread 后不能继承其他类。


    方法二:实现 Runnable 接口

    特点:

    • 实现 Runnable 接口,并重写 run() 方法。
    • 使用 Thread 类包装 Runnable 对象。

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class MyRunnable implements Runnable {
    @Override
    public void run() {
    System.out.println("线程 " + Thread.currentThread().getName() + " 正在运行");
    }
    }

    public class Main {
    public static void main(String[] args) {
    Thread t1 = new Thread(new MyRunnable());
    Thread t2 = new Thread(new MyRunnable());
    t1.start();
    t2.start();
    }
    }

    优点:

    • 更灵活,适合需要共享资源的场景。
    • 可以通过实现接口避免 Java 的单继承限制。

    缺点: 代码稍微复杂一点,需要通过 Thread 对象启动。


    方法三:使用 CallableFuture

    特点:

    • 使用 Callable 接口,可以有返回值,并抛出异常。
    • 使用 FutureTask 获取线程的执行结果。

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import java.util.concurrent.*;

    class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
    Thread.sleep(1000);
    return "线程 " + Thread.currentThread().getName() + " 执行完成";
    }
    }

    public class Main {
    public static void main(String[] args) throws Exception {
    MyCallable callable = new MyCallable();
    FutureTask<String> futureTask = new FutureTask<>(callable);
    Thread thread = new Thread(futureTask);
    thread.start();

    // 获取线程执行结果
    System.out.println("结果: " + futureTask.get());
    }
    }

    优点:

    • 有返回值,可以获取任务执行结果。
    • 可以捕获异常,进行更好的异常处理。

    缺点: 代码较复杂,需要额外处理 FutureTask


    总结:选择哪种方式?

    场景 推荐方法 原因
    简单任务,无需返回结果 Thread 代码简单,适合一次性任务
    需要共享资源或避免继承限制 Runnable 接口 更加灵活,推荐优先使用
    需要获取线程执行结果,或可能抛异常 Callable + Future 支持返回值和异常处理