在 Java 中主线程如何知晓创建的子线程是否执行成功?

Sherwin.Wei Lv7

在 Java 中主线程如何知晓创建的子线程是否执行成功?

回答重点

1)**使用 Thread.join()**:

  • 主线程通过调用 join() 方法等待子线程执行完毕。子线程正常结束,说明执行成功,若抛出异常则需要捕获处理。

2)**使用 CallableFuture**:

  • 通过 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();
}
}
}

CallableFuture 代码示例

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();
// 可死循环监听 success 状态
}
}

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();
}
}
}
Comments