在Java中,有多种方式可以创建和运行线程,主要包括继承Thread
类、实现Runnable
接口、使用Callable
和Future
、以及使用Executor
框架。以下是详细的解释和示例代码:
1. 继承 Thread
类
通过继承Thread
类并重写run
方法来创建线程。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
2. 实现 Runnable
接口
通过实现Runnable
接口并将其传递给Thread
对象来创建线程。
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable is running");
}
}
public class Main {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start(); // 启动线程
}
}
3. 使用 Callable
和 Future
Callable
接口类似于Runnable
,但可以返回结果并且可以抛出异常。Future
接口用于表示异步计算的结果。
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;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "Callable result";
}
}
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
MyCallable myCallable = new MyCallable();
Future<String> future = executor.submit(myCallable);
try {
String result = future.get(); // 获取结果
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown(); // 关闭执行器
}
}
}
4. 使用 Executor
框架
Executor
框架提供了一个更高级的接口,用于管理线程池和并发任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable task1 = () -> {
System.out.println("Task 1 is running");
};
Runnable task2 = () -> {
System.out.println("Task 2 is running");
};
executor.execute(task1);
executor.execute(task2);
executor.shutdown(); // 关闭执行器
}
}
5. 使用 ForkJoinPool
框架
ForkJoinPool
是Java 7引入的,用于并行执行任务的框架,适合处理递归任务。
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class MyRecursiveTask extends RecursiveTask<Integer> {
private static final int THRESHOLD = 10;
private int start;
private int end;
public MyRecursiveTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= THRESHOLD) {
int sum = 0;
for (int i = start; i <= end; i++) {
sum += i;
}
return sum;
} else {
int middle = (start + end) / 2;
MyRecursiveTask leftTask = new MyRecursiveTask(start, middle);
MyRecursiveTask rightTask = new MyRecursiveTask(middle + 1, end);
leftTask.fork();
rightTask.fork();
return leftTask.join() + rightTask.join();
}
}
}
public class Main {
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
MyRecursiveTask task = new MyRecursiveTask(1, 100);
int result = forkJoinPool.invoke(task);
System.out.println("Result: " + result);
}
}
总结
- 继承
Thread
类:简单,但不灵活,因为Java不支持多继承。 - 实现
Runnable
接口:灵活,可以共享同一个Runnable
实例。 - 使用
Callable
和Future
:适用于需要返回结果的任务。 - 使用
Executor
框架:适用于需要线程池管理的并发任务。 - 使用
ForkJoinPool
框架:适用于需要分而治之的递归任务。
根据具体需求选择合适的线程创建方式,可以有效提高程序的并发性能和可维护性。