Skip to content

创建线程的方式有几种

继承 Thread

这是最直接的一种方式,通过创建一个继承自 Thread 类的子类,并重写其 run() 方法来定义线程需要执行的任务。

实现步骤: 1. 定义一个类继承 Thread 类。 2. 重写 run() 方法,将线程要执行的逻辑代码放入其中。 3. 创建该子类的实例,即创建了线程对象。 4. 调用线程对象的 start() 方法来启动线程。

示例:

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("通过继承Thread类创建线程...");
    }
}

// 启动线程
MyThread t = new MyThread();
t.start();

实现 Runnable 接口

这种方式下,线程的执行任务(Runnable)与线程的创建和管理(Thread)是分离的。

实现步骤: 1. 定义一个类实现 Runnable 接口。 2. 实现 run() 方法,这个方法是线程的执行体。 3. 创建 Runnable 实现类的实例。 4. 将该实例作为参数传递给 Thread 类的构造函数来创建线程对象。 5. 调用 Thread 对象的 start() 方法。

示例:

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("通过实现Runnable接口创建线程...");
    }
}

// 启动线程
MyRunnable myRunnable = new MyRunnable();
Thread t = new Thread(myRunnable);
t.start();

实现 Callable 接口(配合 FutureTask 或线程池)

从Java 1.5开始引入,这种方式是对 Runnable 的一个重要补充,主要用于需要获取线程执行结果或处理线程抛出异常的场景。

实现步骤: 1. 创建一个类实现 Callable<V> 接口,其中 V 是返回值的类型。 2. 实现 call() 方法,该方法有返回值,并且可以抛出异常。 3. 使用 FutureTask 类来包装 Callable 对象。 4. 将 FutureTask 对象作为参数传递给 Thread 构造函数并启动线程。 5. 通过 FutureTask 对象的 get() 方法获取线程执行的返回值(该方法会阻塞,直到任务完成)。

示例:

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

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

// 启动线程并获取结果
MyCallable myCallable = new MyCallable();
FutureTask<String> futureTask = new FutureTask<>(myCallable);
Thread t = new Thread(futureTask);
t.start();

// 获取返回值
String result = futureTask.get(); // 阻塞等待
System.out.println(result);

使用线程池

在实际开发中,频繁地创建和销毁线程会带来很大的性能开销。因此,更推荐使用线程池来管理线程。线程池可以复用已创建的线程,控制并发线程的数量。

实现步骤: 1. 使用 Executors 工厂类创建所需类型的线程池(如 newFixedThreadPool, newCachedThreadPool 等)。 2. 创建实现了 RunnableCallable 接口的任务。 3. 通过线程池的 submit()execute() 方法提交任务。 4. 当不再需要线程池时,调用 shutdown() 方法关闭。

示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

// ... MyRunnable class from above ...

// 创建线程池并提交任务
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(new MyRunnable());
executorService.shutdown();