Java 创建线程的方式
Java 提供了多种创建线程的方式。理解不同的创建方式及其适用场景是掌握多线程编程的基础。本章将详细介绍 Java 中创建线程的各种方法。
继承 Thread 类
基本方式
继承 Thread 类并重写 run() 方法:
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行:" + Thread.currentThread().getName());
}
}
// 使用
MyThread thread = new MyThread();
thread.start(); // 启动线程
完整示例
public class ThreadExtendExample extends Thread {
private String threadName;
public ThreadExtendExample(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " 执行:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadExtendExample thread1 = new ThreadExtendExample("线程1");
ThreadExtendExample thread2 = new ThreadExtendExample("线程2");
thread1.start();
thread2.start();
}
}
优缺点
优点:
- 简单直接
- 可以直接使用 Thread 类的方法
缺点:
- Java 单继承,不能继承其他类
- 不符合面向对象设计原则(继承应该表示"是一个"关系)
实现 Runnable 接口
基本方式
实现 Runnable 接口并实现 run() 方法:
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程执行:" + Thread.currentThread().getName());
}
}
// 使用
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
完整示例
public class RunnableExample implements Runnable {
private String taskName;
public RunnableExample(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(taskName + " 执行:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Runnable task1 = new RunnableExample("任务1");
Runnable task2 = new RunnableExample("任务2");
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
thread1.start();
thread2.start();
}
}
使用 Lambda 表达式(Java 8+)
// 使用 Lambda 表达式
Runnable task = () -> {
System.out.println("线程执行");
};
Thread thread = new Thread(task);
thread.start();
// 或直接
Thread thread2 = new Thread(() -> {
System.out.println("线程执行");
});
thread2.start();
优缺点
优点:
- 可以继承其他类
- 符合面向对象设计原则
- 任务和线程分离
- 可以共享同一个 Runnable 对象
缺点:
- 不能直接获取返回值
- 不能抛出检查型异常
Callable 与 Future
Callable 接口
Callable 接口类似于 Runnable,但可以返回值和抛出异常。
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Future 接口
Future 接口表示异步计算的结果。
public interface Future<V> {
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
}
使用示例
import java.util.concurrent.*;
public class CallableExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
// 创建 Callable 任务
Callable<Integer> task = () -> {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
};
// 提交任务,返回 Future
Future<Integer> future = executor.submit(task);
// 获取结果(阻塞)
Integer result = future.get();
System.out.println("结果:" + result);
executor.shutdown();
}
}
FutureTask
**FutureTask**是 Runnable 和 Future 的实现,可以包装 Callable。
Callable<Integer> task = () -> {
Thread.sleep(2000);
return 42;
};
FutureTask<Integer> futureTask = new FutureTask<>(task);
Thread thread = new Thread(futureTask);
thread.start();
// 获取结果
Integer result = futureTask.get(); // 阻塞直到任务完成
System.out.println("结果:" + result);
示例:并发任务执行
示例 1:继承 Thread
public class ThreadExtendDemo extends Thread {
private int taskId;
public ThreadExtendDemo(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("任务 " + taskId + " 开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务 " + taskId + " 执行完成");
}
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
ThreadExtendDemo thread = new ThreadExtendDemo(i);
thread.start();
}
}
}
示例 2:实现 Runnable
public class RunnableDemo implements Runnable {
private int taskId;
public RunnableDemo(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("任务 " + taskId + " 开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务 " + taskId + " 执行完成");
}
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
Runnable task = new RunnableDemo(i);
Thread thread = new Thread(task);
thread.start();
}
}
}
示例 3:使用 Callable 和 Future
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.List;
public class CallableDemo {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<Integer>> futures = new ArrayList<>();
// 提交多个任务
for (int i = 1; i <= 5; i++) {
final int taskId = i;
Callable<Integer> task = () -> {
System.out.println("任务 " + taskId + " 开始执行");
Thread.sleep(2000);
System.out.println("任务 " + taskId + " 执行完成");
return taskId * 10;
};
Future<Integer> future = executor.submit(task);
futures.add(future);
}
// 获取所有结果
for (Future<Integer> future : futures) {
Integer result = future.get();
System.out.println("任务结果:" + result);
}
executor.shutdown();
}
}
示例 4:Lambda 表达式创建线程
public class LambdaThreadDemo {
public static void main(String[] args) {
// 方式 1:直接使用 Lambda
new Thread(() -> {
System.out.println("线程执行");
}).start();
// 方式 2:使用变量
Runnable task = () -> {
for (int i = 0; i < 5; i++) {
System.out.println("执行:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
}
}
示例 5:综合示例
import java.util.concurrent.*;
public class ThreadCreationSummary {
public static void main(String[] args) throws Exception {
// 方式 1:继承 Thread
Thread thread1 = new Thread() {
@Override
public void run() {
System.out.println("方式1:继承 Thread");
}
};
thread1.start();
// 方式 2:实现 Runnable
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("方式2:实现 Runnable");
}
});
thread2.start();
// 方式 3:Lambda 表达式
Thread thread3 = new Thread(() -> {
System.out.println("方式3:Lambda 表达式");
});
thread3.start();
// 方式 4:Callable + Future
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
return "方式4:Callable + Future";
});
System.out.println(future.get());
executor.shutdown();
}
}