在 Java 中,创建线程有三种主要方式:继承 Thread 类、实现 Runnable 接口和使用 Callable 和 Future。下面分别介绍这三种方式。
1. 继承 Thread 类
通过继承 Thread 类并重写其 run() 方法来创建线程。
步骤:
- 创建一个类继承
Thread类。 - 重写
run()方法,该方法是线程执行的主体。 - 创建该类的实例,并调用
start()方法启动线程。
示例代码:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running: " + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
注意:
start()方法会启动线程,并自动调用run()方法。- 不要直接调用
run()方法,否则它只是普通的方法调用,不会启动新线程。
2. 实现 Runnable 接口
通过实现 Runnable 接口并实现其 run() 方法来创建线程。
步骤:
- 创建一个类实现
Runnable接口。 - 实现
run()方法,定义线程执行的任务。 - 创建
Thread对象时,将实现了Runnable的对象作为参数传入。 - 调用
Thread对象的start()方法启动线程。
示例代码:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable is running: " + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start(); // 启动线程
}
}
优点:
- 使用
Runnable接口可以避免单继承的限制(Java 中类只能继承一个父类)。 - 更加灵活,适合资源共享的情况。
3. 使用 Callable 和 Future
Callable 接口与 Runnable 类似,但它可以返回结果并且可以抛出异常。Callable 需要与 FutureTask 或 ExecutorService 配合使用。
步骤:
- 创建一个类实现
Callable接口,并实现call()方法。 call()方法可以返回结果,并且可以抛出异常。- 使用
FutureTask包装Callable对象。 - 将
FutureTask对象传递给Thread并启动线程。 - 使用
FutureTask的get()方法获取线程执行的结果。
示例代码:
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Callable is running: " + Thread.currentThread().getName());
return 42; // 返回结果
}
}
public class Main {
public static void main(String[] args) throws Exception {
MyCallable myCallable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
Thread thread = new Thread(futureTask);
thread.start();
// 获取线程执行的结果
Integer result = futureTask.get();
System.out.println("Result from Callable: " + result);
}
}
优点:
Callable可以返回结果,而Runnable不能。Callable可以抛出异常,便于错误处理。
总结
| 方式 | 特点 |
|---|---|
继承 Thread |
简单易用,但不灵活,无法继承其他类。 |
实现 Runnable |
灵活,适合资源共享,避免了单继承的限制。 |
使用 Callable |
可以返回结果,支持异常处理,适合需要获取线程执行结果的场景。 |
通常情况下,推荐使用 Runnable 或 Callable 来创建线程,因为它们更加灵活,尤其是当需要共享资源或获取线程执行结果时。










