在 Java 中,主线程可以通过多种方式知晓创建的子线程是否执行成功。以下是几种常见的实现方式:
1. 使用 Thread.join()
方法
- 作用:主线程调用子线程的
join()
方法,等待子线程执行完毕。 - 实现:
- 主线程调用
join()
后,会阻塞直到子线程执行完成。 - 可以通过子线程的返回值或状态判断是否执行成功。
- 主线程调用
示例:
public class JoinExample {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("子线程开始执行");
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行完毕");
});
thread.start();
thread.join(); // 主线程等待子线程执行完毕
System.out.println("主线程知晓子线程执行完毕");
}
}
2. 使用 Future
和 Callable
- 作用:通过
ExecutorService
提交一个Callable
任务,返回一个Future
对象。 - 实现:
- 主线程可以通过
Future.get()
方法获取子线程的执行结果。 - 如果子线程执行成功,
Future.get()
会返回结果;如果子线程抛出异常,Future.get()
会抛出ExecutionException
。
- 主线程可以通过
示例:
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
System.out.println("子线程开始执行");
Thread.sleep(1000); // 模拟耗时操作
System.out.println("子线程执行完毕");
return "执行成功";
});
String result = future.get(); // 主线程获取子线程的执行结果
System.out.println("子线程执行结果: " + result);
executor.shutdown();
}
}
3. 使用 CompletableFuture
- 作用:
CompletableFuture
是 Java 8 引入的增强版Future
,支持更灵活的异步编程。 - 实现:
- 主线程可以通过
CompletableFuture
的回调方法(如thenAccept
、exceptionally
)处理子线程的执行结果或异常。
- 主线程可以通过
示例:
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("子线程开始执行");
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行完毕");
return "执行成功";
});
future.thenAccept(result -> {
System.out.println("子线程执行结果: " + result);
}).exceptionally(ex -> {
System.out.println("子线程执行失败: " + ex.getMessage());
return null;
});
// 主线程继续执行其他任务
System.out.println("主线程继续执行");
}
}
4. 使用共享变量
- 作用:通过共享变量(如
volatile
变量或原子类)传递子线程的执行状态。 - 实现:
- 子线程执行完成后,更新共享变量的状态。
- 主线程通过轮询或等待共享变量的状态变化来判断子线程是否执行成功。
示例:
public class SharedVariableExample {
private static volatile boolean isSuccess = false;
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("子线程开始执行");
try {
Thread.sleep(1000); // 模拟耗时操作
isSuccess = true; // 子线程执行成功
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行完毕");
});
thread.start();
while (!isSuccess) {
Thread.sleep(100); // 主线程等待子线程执行成功
}
System.out.println("主线程知晓子线程执行成功");
}
}
5. 使用 CountDownLatch
- 作用:
CountDownLatch
是一个同步工具,用于等待一个或多个线程完成。 - 实现:
- 主线程通过
CountDownLatch.await()
等待子线程执行完成。 - 子线程执行完成后,调用
CountDownLatch.countDown()
通知主线程。
- 主线程通过
示例:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
Thread thread = new Thread(() -> {
System.out.println("子线程开始执行");
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行完毕");
latch.countDown(); // 通知主线程
});
thread.start();
latch.await(); // 主线程等待子线程执行完毕
System.out.println("主线程知晓子线程执行完毕");
}
}
6. 总结
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Thread.join() | 简单易用 | 主线程会阻塞 | 简单的线程等待场景 |
Future 和 Callable | 支持返回值,异常处理 | 需要线程池,主线程会阻塞 | 需要获取执行结果的场景 |
CompletableFuture | 支持回调,灵活性高 | 需要理解异步编程模型 | 复杂的异步编程场景 |
共享变量 | 简单 | 需要轮询,可能浪费 CPU 资源 | 简单的状态共享场景 |
CountDownLatch | 支持多个线程同步 | 需要额外的同步工具 | 多线程协同场景 |
根据具体需求选择合适的方式,主线程可以有效地知晓子线程是否执行成功。
THE END
暂无评论内容