如何处理线程返回的值

本文详细介绍四种在Java中从多线程获取数据的方法:主线程等待法、使用Thread的join阻塞、通过Callable的FutureTask以及使用线程池的Future实现。每种方法都附带了详细的代码示例,帮助读者深入理解并掌握多线程编程中的数据同步技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)主线程等待法

package com.interview.thread;
 
//获取多线程返回值1:主线程等待
public class CycleWait implements Runnable{
    private String value;
 
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.value = "we have data now";
    }
    public static void main(String[] args) throws InterruptedException {
        CycleWait cw = new CycleWait();
        Thread t1 = new Thread(cw);
        t1.start();
        while(cw.value == null) {
                Thread.sleep(100);
        }
        System.out.println("value:" + cw.value);
    }
 
}
(2)使用Thread的join阻塞当前线程等待

package com.interview.thread;
 
//获取多线程返回值1:主线程等待
public class CycleWait implements Runnable{
    private String value;
 
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.value = "we have data now";
    }
    public static void main(String[] args) throws InterruptedException {
        CycleWait cw = new CycleWait();
        Thread t1 = new Thread(cw);
        t1.start();
        t1.join();
        System.out.println("value:" + cw.value);
    }
 
}
(3)通过Callable的FutureTask

package com.interview.thread;
 
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
 
 
 
public class FutureTaskDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        FutureTask<String> task = new FutureTask<>(new MyCallable());
        new Thread(task).start();
        if(!task.isDone()) {
            System.out.println("任务未处理完成。。");
        }
        System.out.println("任务执行结果:" + task.get());
    }
}
class MyCallable implements Callable<String>{
 
    @Override
    public String call() throws Exception {
        
        String value = "result value";
        System.out.println("线程开始处理任务");
        Thread.sleep(5000);
        System.out.println("线程结束处理任务");
        return value;
    }
 
}
(4)通过Callable接口,线程池的Future实现

package com.interview.thread;
 
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
 
 
 
public class FutureTaskDemo {
    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newCachedThreadPool();
        Future<String> future = pool.submit(new MyCallable());
        if(!future.isDone()) {
            System.out.println("等待任务...");
        }
        System.out.println("结果:" + future.get());
        pool.shutdown();
    }
}
 
class MyCallable implements Callable<String>{
 
    @Override
    public String call() throws Exception {
        
        String value = "result value";
        System.out.println("线程开始处理任务");
        Thread.sleep(5000);
        System.out.println("线程结束处理任务");
        return value;
    }
 
}
 
————————————————
版权声明:本文为优快云博主「Pastthewind」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/Pastthewind/article/details/101000305

### CreateThread 函数的详细信息与用法 #### 背景说明 `CreateThread` 是 Windows API 中用于创建新线程的核心函数。通过此函数,开发者可以在进程中启动新的执行路径,实现多线程编程以提升性能或改善用户体验。以下是有关 `CreateThread` 的详细介绍及其典型用法。 --- #### CreateThread 函数定义 `CreateThread` 的原型如下所示: ```c HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, __drv_aliasesMem LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); ``` 各参数含义解释如下: 1. **lpThreadAttributes**: 指向 SECURITY_ATTRIBUTES 结构的指针,决定返回句柄是否可继承,默认传入 NULL 即不可继承。 2. **dwStackSize**: 设置新线程栈大小(单位为字节)。若设为 0,则使用默认堆栈大小[^1]。 3. **lpStartAddress**: 线程入口点函数地址,即线程开始执行时调用的回调函数。 4. **lpParameter**: 向线程传递的参数,通常是一个指向结构体或其他数据类型的指针。 5. **dwCreationFlags**: 控制线程初始状态的标志位。常用有 0(立即运行)和 CREATE_SUSPENDED(挂起状态待恢复)[^2]。 6. **lpThreadId**: 返回线程 ID 的变量地址,可用于后续跟踪线程活动。 成功调用后返回一个有效的线程句柄;失败则返回 NULL 并可通过 `GetLastError()` 获取具体错误码。 --- #### 示例代码 以下提供了一个完整的 C++ 实现示例,演示如何使用 `CreateThread` 创建并管理线程: ```cpp #include <windows.h> #include <iostream> // 定义线程处理函数 DWORD WINAPI MyThreadFunction(LPVOID lpParam) { int threadId = reinterpret_cast<int>(lpParam); std::cout << "Thread #" << threadId << " is running." << std::endl; Sleep(2000); // 让线程休眠两秒钟模拟工作负载 std::cout << "Thread #" << threadId << " finished execution." << std::endl; return threadId; // 返回线程编号作为退出代码 } int main() { HANDLE threads[3]; // 存储三个线程的句柄 DWORD threadIds[3]; // 存储对应的线程ID for (int i = 0; i < 3; ++i) { threads[i] = CreateThread( NULL, // 默认安全性属性 0, // 使用默认堆栈大小 MyThreadFunction, // 线程入口点 reinterpret_cast<LPVOID>(i + 1), // 参数:线程编号 0, // 立即运行 &threadIds[i] // 输出线程ID ); if (!threads[i]) { std::cerr << "Failed to create thread!" << std::endl; return GetLastError(); // 处理错误 } } // 等待所有线程结束 WaitForMultipleObjects(3, threads, TRUE, INFINITE); // 关闭线程句柄释放资源 for (int i = 0; i < 3; ++i) { CloseHandle(threads[i]); } std::cout << "All threads have completed their tasks." << std::endl; return 0; } ``` 在这个例子中,我们创建了三个独立工作的线程,并分别打印它们的消息。最后主线程等待所有子线程完成后才继续向前推进。 --- #### 注意事项 - 若多个线程需访问共享资源,应采取适当措施防止竞态条件的发生,比如借助互斥量 (`Mutex`) 或临界区 (`Critical Section`) 进行同步保护。 - 对于长时间运行的任务建议设置合理的优先级以免影响其他重要进程的表现。 - 切记适时关闭不再使用的线程句柄以防泄露系统资源。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值