在Java中,创建线程主要有三种方法:继承Thread
类、实现Runnable
接口和使用Callable
接口。每种方法都有其特点和适用场景。下面详细介绍这三种方法:
1. 继承Thread
类
通过继承Thread
类并重写其run
方法来创建线程。这是最简单直接的方法,但由于Java不支持多继承,因此这种方法在需要继承其他类时会受到限制。
示例代码
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start();
thread2.start();
}
}
2. 实现Runnable
接口
通过实现Runnable
接口并重写其run
方法来创建线程。这种方法更灵活,因为Java支持多实现,可以在实现Runnable
接口的同时继承其他类。
示例代码
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable());
Thread thread2 = new Thread(new MyRunnable());
thread1.start();
thread2.start();
}
}
3. 使用Callable
接口
通过实现Callable
接口并重写其call
方法来创建线程。与Runnable
接口不同,Callable
接口可以返回结果并抛出异常。通常与Future
和ExecutorService
一起使用。
示例代码
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += i;
System.out.println(Thread.currentThread().getName() + " - " + i);
Thread.sleep(1000); // 模拟耗时操作
}
return sum;
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<Integer> future1 = executorService.submit(new MyCallable());
Future<Integer> future2 = executorService.submit(new MyCallable());
try {
Integer result1 = future1.get();
Integer result2 = future2.get();
System.out.println("Result from thread1: " + result1);
System.out.println("Result from thread2: " + result2);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
总结
- 继承
Thread
类:简单直接,但受限于Java的单继承。 - 实现
Runnable
接口:更灵活,支持多实现,适用于大多数场景。 - 使用
Callable
接口:可以返回结果并抛出异常,通常与Future
和ExecutorService
一起使用,适用于需要获取线程执行结果的场景。
选择哪种方法取决于具体需求和场景。通常情况下,推荐使用Runnable
接口,因为它更灵活且符合面向接口编程的原则。