1. 程式人生 > 其它 >【Java】+多執行緒 [有返回值]+等待建立的執行緒 中的 所有執行緒都結束(再開始執行主執行緒)

【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