**方法 1:继承 Thread 类**
通过继承 `Thread` 类并重写 `run()` 方法创建线程,然后调用 `start()` 启动线程,最后使用 `join()` 让主线程等待。
java
public class ThreadExample {
public static void main(String[] args) {
System.out.println("主线程开始");
// 创建并启动子线程
MyThread myThread = new MyThread();
myThread.start();
try {
// 主线程等待子线程执行完毕
myThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束");
}
}
// 继承 Thread 类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("子线程开始执行");
try {
// 模拟耗时操作
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行完毕");
}
}
**输出结果:**
主线程开始
子线程开始执行
子线程执行完毕
主线程结束
**方法 2:实现 Runnable 接口**
通过实现 `Runnable` 接口创建任务,再将任务传递给 `Thread` 对象,最后调用 `join()` 方法。
java
public class RunnableExample {
public static void main(String[] args) {
System.out.println("主线程开始");
// 创建任务
MyRunnable task = new MyRunnable();
// 将任务传递给 Thread 对象
Thread thread = new Thread(task);
// 启动线程
thread.start();
try {
// 主线程等待子线程执行完毕
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束");
}
}
// 实现 Runnable 接口
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("子线程开始执行");
try {
// 模拟耗时操作
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行完毕");
}
}
**输出结果与上例相同。**
**关键说明:**
1. **`join()` 方法**:
- 主线程调用 `thread.join()` 后会被阻塞,直到 `thread` 执行完毕。
- 可传入超时参数(如 `join(1000)`),表示最多等待 1 秒。
2. **线程安全**:
- `join()` 是线程安全的,多个线程可同时调用同一个线程的 `join()`。
3. **异常处理**:
- `join()` 可能抛出 `InterruptedException`,需进行异常处理。
**进阶:创建多个线程并等待所有线程完成**
如果需要创建多个线程并等待它们全部完成,可以这样做:
java
public class MultipleThreadsExample {
public static void main(String[] args) throws InterruptedException {
System.out.println("主线程开始");
// 创建多个线程
Thread t1 = new Thread(() -> {
System.out.println("线程1开始");
sleep(1000);
System.out.println("线程1结束");
});
Thread t2 = new Thread(() -> {
System.out.println("线程2开始");
sleep(1500);
System.out.println("线程2结束");
});
// 启动线程
t1.start();
t2.start();
// 等待所有线程完成
t1.join();
t2.join();
System.out.println("主线程结束");
}
private static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
**输出结果:**
主线程开始
线程1开始
线程2开始
线程1结束
线程2结束
主线程结束
**总结**
- **继承 Thread 类**:简单直接,但 Java 不支持多重继承,灵活性较低。
- **实现 Runnable 接口**:推荐方式,避免单继承限制,便于共享资源。
- **`join()` 方法**:确保主线程等待子线程完成,常用于线程同步。