You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

并发编程-线程:实现run_both方法,多线程执行函数并返回结果

Java实现run_both方法:多线程执行函数并返回结果元组

核心实现思路

  • 用Supplier<T>函数式接口定义带返回值的任务,匹配无参、返回结果的需求
  • 借助AtomicReference存储线程执行结果,保证线程安全
  • 启动线程后调用join()等待所有线程完成,确保能获取有效结果
  • 将两个结果封装为元组返回(可自定义元组类或用JDK自带容器)

完整代码实现

import java.util.function.Supplier;
import java.util.concurrent.atomic.AtomicReference;

// 自定义轻量级元组类,用于封装两个返回结果
class Tuple<A, B> {
    public final A first;
    public final B second;

    public Tuple(A first, B second) {
        this.first = first;
        this.second = second;
    }
}

public class DualThreadRunner {

    /**
     * 执行两个任务在独立线程,返回结果元组
     * @param task1 第一个带返回值的任务
     * @param task2 第二个带返回值的任务
     * @return 包含两个任务结果的元组
     * @throws InterruptedException 线程等待被中断时抛出
     */
    public static <A, B> Tuple<A, B> run_both(Supplier<A> task1, Supplier<B> task2) throws InterruptedException {
        AtomicReference<A> result1 = new AtomicReference<>();
        AtomicReference<B> result2 = new AtomicReference<>();

        // 启动第一个线程执行任务1
        Thread t1 = new Thread(() -> result1.set(task1.get()));
        // 启动第二个线程执行任务2
        Thread t2 = new Thread(() -> result2.set(task2.get()));

        t1.start();
        t2.start();

        // 等待两个线程执行完成,避免主线程提前返回空结果
        t1.join();
        t2.join();

        return new Tuple<>(result1.get(), result2.get());
    }

    // 测试示例(对应你给出的代码逻辑)
    public static void main(String[] args) throws InterruptedException {
        // 用数组存储共享变量y和z,满足lambda对外部变量的访问要求
        int[] shared = new int[2]; 

        Tuple<Integer, Void> result = run_both(
                // 对应t1的逻辑:计算y+z
                () -> shared[0] + shared[1],
                // 对应t2的逻辑:赋值y=1,z=2
                () -> {
                    shared[0] = 1;
                    shared[1] = 2;
                    return null;
                }
        );

        System.out.println("任务执行结果:" + result.first); // 输出3
    }
}

关键注意事项

  • 若不想自定义元组,可直接使用JDK自带的AbstractMap.SimpleEntry替代,替换返回语句为:
    return new AbstractMap.SimpleEntry<>(result1.get(), result2.get());
    
  • 线程间共享变量需保证线程安全,示例中用数组是因为lambda只能访问final或等效final的变量,数组引用满足条件且可修改内部元素
  • 必须调用join():如果跳过这一步,主线程可能在子线程完成前就返回,导致结果为null
  • 若任务可能抛出受检异常,需在lambda内部捕获处理,或修改方法签名抛出对应异常

内容的提问来源于stack exchange,提问作者Alexander Gulbrandsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:55:30