【Java】+多线程 [有返回值]+等待创建的线程 中的 所有线程都结束(再开始执行主线程)

一、需要多线程执行的任务

复制代码
package thread;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/**
 * @Author: 
 * @Date: 2022/3/23 10:53
 * @Description:
 * @Version: v1.0
 */
public class Job {
    /**
     * 要让线程执行的任务
     *
     * @param returnDataList 用来保存线程执行任务中需要返回数据的对象(线程要返回什么数据 就往这个对象里塞值就行了)
     * @param count          任务的参数
     */
    public void print(ArrayList<ReturnData> returnDataList, String count) {
        String data = String.format("[%s][%s]%s",
                Thread.currentThread().getName(),
                count,
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSS").format(new Date())
        );
        System.out.println(data);

        // 在任务中把要返回的数据添加到returnData对象中
        ReturnData returnData = new ReturnData();
        returnData.thread = Thread.currentThread();
        returnData.data = data;
        returnDataList.add(returnData);
    }
}
复制代码

 

二、多线程工具封装

备注:可直接调用此封装(仅修改setup1CreateThread方法中对应位置即可)

功能:有线程返回值;等待创建的线程 中的 所有线程都结束(再开始执行主线程)

复制代码
package thread;

import lombok.Data;

import java.util.ArrayList;
import java.util.HashSet;

/**
 * @Author: 
 * @Date: 2022/3/22 16:12
 * @Description:
 * @Version: v1.0
 */

@Data
public class MyThread {
    public ArrayList<Thread> threads;

    // 用来保存线程执行任务中需要返回数据的对象(线程要返回什么数据 就往这个对象里塞值就行了)
    public ArrayList<ReturnData> returnDataList;

    public MyThread() {
        this.threads = new ArrayList<>();
        this.returnDataList = new ArrayList<>();
    }


    /**
     * 创建线程并给线程添加任务
     * 备注:
     * 1、此方法仅需把 new Job().print(returnDataList, taskParam) 替换为待执行的任务方法即可
     * 2、taskParam 随任务的参数而定
     *
     * @param threadCount 要创建的线程数量
     * @param taskParam   任务的参数
     * @return
     */
    public MyThread setup1CreateThread(int threadCount, String taskParam) {
        for (int i = 0; i < threadCount; i++) {
            // new Job().print(returnDataList, taskParam) 为线程要执行的任务
            Thread th = new Thread(() -> new Job().print(returnDataList, taskParam));
            // 设置线程名称
            th.setName(String.format("MyThread-%s", i + 1));
            threads.add(th);
        }
        return this;
    }

    /**
     * 批量启动所有线程
     * 备注:此方法不用修改
     *
     * @return
     */
    public MyThread setup2Starts() {
        for (Thread thread : threads) {
            thread.start();
        }
        return this;
    }

    /**
     * 等待threads中的所有线程都结束(再开始执行主线程)
     * 备注:此方法不用修改
     *
     * @return
     */
    public MyThread setup3WaitThreadEnd() {
        while (true) {
            ArrayList<String> thStates = new ArrayList<>();
            for (Thread thread : threads) {
                thStates.add(thread.getState().name());
            }
            // 第一个线程的状态为终止状态 && 所有线程的状态去重后数量为1(表示所有的线程状态都相同)
            if (threads.get(0).getState().name().equals("TERMINATED") && new HashSet<Object>(thStates).size() == 1) {
                break;
            }
        }
        return this;
    }


    public static void main(String[] args) {
        MyThread myThread = new MyThread()
                // 1 创建线程并给线程添加任务(此时线程还未执行)
                .setup1CreateThread(10, "这是任务的参数")
                // 2 批量启动所有线程
                .setup2Starts()
                // 3 等待创建的线程 中的 所有线程都结束(再开始执行主线程)
                .setup3WaitThreadEnd();

        System.out.println("创建的所有线程执行完后 才会执行此行");

        for (ReturnData returnData : myThread.returnDataList) {
            System.out.println(String.format("线程执行任务的返回数据:%s %s", returnData.thread.getName(), returnData.data));
        }
    }
}
复制代码

 

三、保存返回数据的对象

复制代码
package thread;

import lombok.Data;

/**
 * @Author: 
 * @Date: 2022/3/23 13:49
 * @Description: 用来保存线程执行任务中需要返回数据的对象(线程要返回什么数据 就往这个对象里塞值就行了)
 * @Version: v1.0
 */

@Data
public class ReturnData {
    /**
     * 线程
     */
    public Thread thread;

    /**
     * 当前线程执行任务所保存的数据
     */
    public Object data;
}
复制代码

 

四、效果

复制代码
[MyThread-5][这是任务的参数]2022-03-23 14:15:48.00699
[MyThread-2][这是任务的参数]2022-03-23 14:15:48.00699
[MyThread-1][这是任务的参数]2022-03-23 14:15:48.00701
[MyThread-6][这是任务的参数]2022-03-23 14:15:48.00702
[MyThread-7][这是任务的参数]2022-03-23 14:15:48.00707
[MyThread-3][这是任务的参数]2022-03-23 14:15:48.00710
[MyThread-4][这是任务的参数]2022-03-23 14:15:48.00710
[MyThread-8][这是任务的参数]2022-03-23 14:15:48.00711
[MyThread-9][这是任务的参数]2022-03-23 14:15:48.00712
[MyThread-10][这是任务的参数]2022-03-23 14:15:48.00713
创建的所有线程执行完后 才会执行此行
线程执行任务的返回数据:MyThread-5 [MyThread-5][这是任务的参数]2022-03-23 14:15:48.00699
线程执行任务的返回数据:MyThread-2 [MyThread-2][这是任务的参数]2022-03-23 14:15:48.00699
线程执行任务的返回数据:MyThread-1 [MyThread-1][这是任务的参数]2022-03-23 14:15:48.00701
线程执行任务的返回数据:MyThread-6 [MyThread-6][这是任务的参数]2022-03-23 14:15:48.00702
线程执行任务的返回数据:MyThread-7 [MyThread-7][这是任务的参数]2022-03-23 14:15:48.00707
线程执行任务的返回数据:MyThread-3 [MyThread-3][这是任务的参数]2022-03-23 14:15:48.00710
线程执行任务的返回数据:MyThread-4 [MyThread-4][这是任务的参数]2022-03-23 14:15:48.00710
线程执行任务的返回数据:MyThread-8 [MyThread-8][这是任务的参数]2022-03-23 14:15:48.00711
线程执行任务的返回数据:MyThread-9 [MyThread-9][这是任务的参数]2022-03-23 14:15:48.00712
线程执行任务的返回数据:MyThread-10 [MyThread-10][这是任务的参数]2022-03-23 14:15:48.00713
复制代码

 

posted @   淡怀  阅读(299)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示

目录导航