在 Java 中主线程如何知晓创建的子线程是否执行成功?
在 Java 中主线程如何知晓创建的子线程是否执行成功?
回答重点
1)**使用 Thread.join()**:
- 主线程通过调用
join() 方法等待子线程执行完毕。子线程正常结束,说明执行成功,若抛出异常则需要捕获处理。
2)**使用 Callable 和 Future**:
- 通过
Callable 创建可返回结果的任务,并通过 Future.get() 获取子线程的执行结果或捕获异常。Future.get() 会阻塞直到任务完成,若任务正常完成,返回结果,否则抛出异常。
3)使用回调机制:
- 可以通过自定义回调机制,主线程传入一个回调函数,子线程完成后调用该函数并传递执行结果。这样可以非阻塞地通知主线程任务完成情况。
4)使用 CountDownLatch或其他 JUC 相关类:
- 主线程通过
CountDownLatch 来等待子线程完成。当子线程执行完毕后调用 countDown(),主线程通过 await() 等待子线程完成任务。
扩展知识
Thread.join() 代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class ThreadJoinExample { public static void main(String[] args) { Thread t = new Thread(() -> { try { Thread.sleep(1000); System.out.println("子线程执行完成"); } catch (InterruptedException e) { e.printStackTrace(); } });
t.start();
try { t.join(); System.out.println("主线程确认子线程执行完毕"); } catch (InterruptedException e) { e.printStackTrace(); } } }
|
Callable 和 Future 代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import java.util.concurrent.*;
public class CallableFutureExample { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Boolean> task = () -> { try { Thread.sleep(1000); System.out.println("子线程执行完成"); return true; } catch (InterruptedException e) { e.printStackTrace(); return false; } };
Future<Boolean> future = executor.submit(task);
try { boolean result = future.get(); System.out.println("子线程执行成功:" + result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } finally { executor.shutdown(); } } }
|
回调机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class CallbackExample { interface Callback { void onComplete(boolean success); }
static class WorkerThread extends Thread { private final Callback callback;
WorkerThread(Callback callback) { this.callback = callback; }
@Override public void run() { try { Thread.sleep(1000); System.out.println("子线程执行完成"); callback.onComplete(true); } catch (InterruptedException e) { e.printStackTrace(); callback.onComplete(false); } } }
public static void main(String[] args) { Callback callback = success -> System.out.println("子线程执行成功: " + success);
WorkerThread worker = new WorkerThread(callback); worker.start(); } }
|
CountDownLatch 示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(1);
Thread t = new Thread(() -> { try { Thread.sleep(1000); System.out.println("子线程执行完成"); } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); } });
t.start();
latch.await(); System.out.println("主线程确认子线程执行完毕"); } }
|
ExecutorCompletionService
可以使用 ExecutorCompletionService 来同时提交多个任务,并获取其执行结果。take() 方法可以从结果队列中获取已完成的任务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import java.util.concurrent.*;
public class CompletionServiceExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executor);
completionService.submit(() -> { Thread.sleep(1000); System.out.println("子线程1执行完成"); return true; });
completionService.submit(() -> { Thread.sleep(500); System.out.println("子线程2执行完成"); return true; });
try { for (int i = 0; i < 2; i++) { Future<Boolean> result = completionService.take(); System.out.println("任务执行成功:" + result.get()); } } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } finally { executor.shutdown(); } } }
|