在 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
来创建线程,因为它们更加灵活,尤其是当需要共享资源或获取线程执行结果时。