首页 > 其他分享 >主线程等待所有其他线程执行完毕,然后再继续执行主线程的逻辑,有以下几种方法可以实现:

主线程等待所有其他线程执行完毕,然后再继续执行主线程的逻辑,有以下几种方法可以实现:

时间:2024-08-13 22:05:07浏览次数:14  
标签:继续执行 Thread 主线 System try 线程 println out

## 1. 使用 `Thread.join()`
`Thread.join()` 方法会让主线程等待被调用线程执行完毕之后再继续执行。

#### 示例代码:

```java
public class Main {
public static void main(String[] args) {
// 创建3个线程
Thread thread1 = new Thread(() -> {
System.out.println("Thread 1 is running");
// 模拟任务耗时
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Thread 1 is done");
});

Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 is running");
try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Thread 2 is done");
});

Thread thread3 = new Thread(() -> {
System.out.println("Thread 3 is running");
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Thread 3 is done");
});

// 启动线程
thread1.start();
thread2.start();
thread3.start();

try {
// 主线程等待子线程执行完毕
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

// 主线程继续执行
System.out.println("All threads have finished. Main thread continues.");
}
}
```

#### 解释:
- `thread1.join()` 会让主线程等待 `thread1` 执行完毕后再继续往下执行。
- `thread2.join()` 和 `thread3.join()` 也类似。
- 当所有线程都执行完毕后,主线程会继续执行接下来的逻辑。

### 2. 使用 `ExecutorService` 和 `awaitTermination()`
`ExecutorService` 提供了管理线程池的能力,使用它可以方便地等待所有任务执行完毕。

#### 示例代码:

```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);

// 提交3个任务
executor.submit(() -> {
System.out.println("Task 1 is running");
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Task 1 is done");
});

executor.submit(() -> {
System.out.println("Task 2 is running");
try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Task 2 is done");
});

executor.submit(() -> {
System.out.println("Task 3 is running");
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Task 3 is done");
});

// 停止接收新的任务,并等待已提交任务执行完毕
executor.shutdown();

try {
// 等待所有任务完成,最多等待10分钟
if (!executor.awaitTermination(10, TimeUnit.MINUTES)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}

// 主线程继续执行
System.out.println("All tasks have finished. Main thread continues.");
}
}
```

#### 解释:
- `executor.shutdown()` 会停止接收新的任务,但会让已经提交的任务继续执行。
- `executor.awaitTermination()` 会等待所有任务完成,等待的时间可以设置。如果超时或者被中断,可以调用 `shutdownNow()` 来强制终止所有线程。

### 3. 使用 `CountDownLatch`
`CountDownLatch` 是一个同步辅助类,用于在一个或多个线程完成一组操作之前,使一个或多个线程等待。

#### 示例代码:

```java
import java.util.concurrent.CountDownLatch;

public class Main {
public static void main(String[] args) {
int numberOfThreads = 3;
CountDownLatch latch = new CountDownLatch(numberOfThreads);

// 创建并启动3个线程
new Thread(() -> {
System.out.println("Thread 1 is running");
try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Thread 1 is done");
latch.countDown(); // 线程结束时,计数器减1
}).start();

new Thread(() -> {
System.out.println("Thread 2 is running");
try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Thread 2 is done");
latch.countDown(); // 线程结束时,计数器减1
}).start();

new Thread(() -> {
System.out.println("Thread 3 is running");
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Thread 3 is done");
latch.countDown(); // 线程结束时,计数器减1
}).start();

try {
// 主线程等待,直到计数器变为0
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}

// 主线程继续执行
System.out.println("All threads have finished. Main thread continues.");
}
}
```

#### 解释:
- 每个线程在执行完任务后调用 `latch.countDown()`,减少计数。
- 主线程调用 `latch.await()` 等待,直到计数器变为0,即所有线程都完成了任务。

### 总结
- **`Thread.join()`** 是最简单直接的方式,但需要手动管理每个线程。
- **`ExecutorService`** 提供了更强大的线程池管理和任务控制功能。
- **`CountDownLatch`** 非常适合需要在多个线程完成各自任务后,再让主线程继续的场景。

根据具体的应用场景和需求,选择最合适的方法来实现。

标签:继续执行,Thread,主线,System,try,线程,println,out
From: https://www.cnblogs.com/rebecca2020/p/18357801

相关文章

  • 进程线程(2)
    父子进程的关系子进程是父进程的副本。子进程获得父进程数据段,堆,栈,正文段共享。        在fork之后,一般情况哪个会先运行,是不确定的。如果非要确定那个要先运行,需要IPC机制。     区别:fork的返回值pid不同进程的创建创建之后,父子进程各自拥有4g独立的内存......
  • 【JVM】jvm 线程栈的一些设置 Thread Size
    1.概述下面是jvm线程栈的一些设置,简单的了解一下。2.XssXss和ThreadStackSize是等价的参数,用于设置Java线程栈的大小,单位为Kb。在命令行中,-Xss100K和-XX:ThreadStackSize=100是表示相同意义的参数。Xss参数的实现:Xss参数是通过设置ThreadStackSize数据......
  • Java线程池学习
    Java线程池学习一、线程池基础1定义2优点3基本组件二、Java线程池实现1Executor接口2ExecutorService接口3ThreadPoolExecutor类3.1创建线程池实例三、执行策略1直接提交策略(DirectSubmissionExecutor)2固定线程数策略(FixedThreadPool)3缓存线程池策略......
  • C 多线程
    C多线程C程序中经常同时执行多项任务。例如,一个程序可能:(1)在执行程序过程中通过完成并行任务来提高性能。(2)在处理用户输入的同时,在后台进行耗时的数据通信和实时操作。通过并行执行(concurrentexecution)程序中的部分代码,可以实现不同任务同时进行。特别是在多处理器系......
  • 游戏安全入门-扫雷分析&远程线程注入
    前言无论学习什么,首先,我们应该有个目标,那么入门windows游戏安全,脑海中浮现出来的一个游戏--扫雷,一款家喻户晓的游戏,虽然已经被大家分析的不能再透了,但是我觉得自己去分析一下还是极好的,把它作为一个小目标再好不过了。我们编写一个妙妙小工具,工具要求实现以下功能:时间暂停、修......
  • PHP 返回结果给前端/ajax后,在后台继续执行代码的方法
    .问题背景在实际项目开发中,遇到一个问题:前端通过Ajax请求后台PHPAPI接口,执行多文件的打包下载操作,该请求由于需要更新大量的数据(日志、统计等信息)到数据库且还需要执行较大的磁盘IO操作,导致该请求很耗时间。由于前端页面的更新需要快速响应,因此需要PHP快速返回计算结果,然......
  • 千万别从系统中创建线程, 看看从线程池中调用的线程的效率(实践篇)
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • 多线程
    多线程1.进程与线程1.1.什么是进程进程就是正在运行的程序,它是系统进行资源分配和调度的基本单位,各个进程之间相互独立,系统给每个进程分配不同的地址空间和资源Win操作系统任务管理器查看应用程序运行的进程1.2.什么是线程线程就是程序(进程)执行的任务(分为单线程和多线程......
  • VS2022+QT6.7.2 子线程与主线程通信(详细)(注释)
    需求:主线程将需要计算的数据发送给子线程,子线程将计算后的结果返回给主线程。实现逻辑:(前提:子线程类已创建好,并使用start方法启动子线程)1、主线程的mysignal1信号触发子线程的myslot2槽函数方法:connect(this,&QtWidgetsApplication13::mysignal1,st,&mythread::myslot2);......
  • 线程与进程
    多线程多线程的创建方式方式1:继承于Thread类1.创建一个集成于Thread类的子类(通过ctrl+o(override)输入run查找run方法)2.重写Thread类的run()方法3.创建Thread子类的对象4.通过此对象调用start()方法start与run方法的区别:start方法的作用:1.启动当前线程2.调用当前线程的重写......