【多线程】让线程返回值

使用Callable处理线程并获取返回值的示例

很多时候,我们使用线程去处理一些业务,并希望得到结果,这时候,我们可以使用Callable。

下面例子,模拟使用线程查询DB得到一个List。

 

例子

线程,返回一个List数据

package com.nicchagil.study.thread.cnblogs.No02可返回值的线程;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class QueryDataThread implements Callable<List<Map<String, Object>>> {
    
    private Map<String, Object> param = null;
    
    public QueryDataThread(Map<String, Object> param) {
        super();
        this.param = param;
    }

    @Override
    public List<Map<String, Object>> call() throws Exception {
        
        /* 模拟查询DB后得到结果集合 */
        System.out.println("param -> " + param);
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("id", "1001");
        map1.put("name", "nick huang");
        
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("id", "1002");
        map2.put("name", "darren lin");
        
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list.add(map1);
        list.add(map2);
        
        /* 设置短暂的睡眠以便观察效果 */
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        return list;
    }
    
}
View Code

 

启动线程,并等待返回结果

package com.nicchagil.study.thread.cnblogs.No02可返回值的线程;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Call {

    public static void main(String[] args) {
        List<Map<String, Object>> list = null;
        try {
            list = query();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if (list != null && list.size() > 0) {
            for (Map<String, Object> map : list) {
                System.out.println("id : " + map.get("id") + ", name : " + map.get("name"));
            }
        }
    }
    
    /**
     * 模拟查询的业务方法
     */
    public static List<Map<String, Object>> query() throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        
        /* 模拟查询参数 */
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("username", "derick");
        
        Future<List<Map<String, Object>>> future = es.submit(new QueryDataThread(param));
        List<Map<String, Object>> list = null;
        try {
            list = future.get();
        } finally {
            es.shutdown();
        }
        
        return list;
    }

}
View Code

 

More?

查询用户数据的线程

package com.nicchagil.study.thread.cnblogs.No02可返回值的线程.No002多个查询;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class QueryDataThread implements Callable<List<Map<String, Object>>> {
    
    private Map<String, Object> param = null;
    
    public QueryDataThread(Map<String, Object> param) {
        super();
        this.param = param;
    }

    @Override
    public List<Map<String, Object>> call() throws Exception {
        
        /* 模拟查询DB后得到结果集合 */
        System.out.println("query user param -> " + param);
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("id", "1001");
        map1.put("name", "nick huang");
        
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("id", "1002");
        map2.put("name", "darren lin");
        
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list.add(map1);
        list.add(map2);
        
        /* 设置短暂的睡眠以便观察效果 */
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        return list;
    }
    
}
View Code

 

查询地址数据的线程

package com.nicchagil.study.thread.cnblogs.No02可返回值的线程.No002多个查询;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class QueryExtDataThread implements Callable<Map<String, Object>> {
    
    private Map<String, Object> param = null;
    
    public QueryExtDataThread(Map<String, Object> param) {
        super();
        this.param = param;
    }

    @Override
    public Map<String, Object> call() throws Exception {
        
        /* 模拟查询DB后得到结果集合 */
        System.out.println("query address param -> " + param);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("1001", "hz");
        map.put("1002", "pl");
        
        /* 设置短暂的睡眠以便观察效果 */
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        return map;
    }
    
}
View Code

 

并发调用查询用户数据和地址数据的线程,然后合并数据,并返回

package com.nicchagil.study.thread.cnblogs.No02可返回值的线程.No002多个查询;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Call {

    public static void main(String[] args) {
        List<Map<String, Object>> list = null;
        try {
            list = query();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if (list != null && list.size() > 0) {
            for (Map<String, Object> map : list) {
                System.out.println(map);
            }
        }
    }
    
    /**
     * 模拟查询的业务方法
     */
    public static List<Map<String, Object>> query() throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        
        /* 模拟查询参数 */
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("username", "derick");
        
        Future<List<Map<String, Object>>> userFuture = es.submit(new QueryDataThread(param));
        Future<Map<String, Object>> addressFuture = es.submit(new QueryExtDataThread(param));
        List<Map<String, Object>> userList = null;
        Map<String, Object> addressMap = null;
        try {
            userList = userFuture.get();
            addressMap = addressFuture.get();
        } finally {
            es.shutdown();
        }
        
        /* 合并业务数据 */
        if (userList != null && userList.size() > 0) {
            for (Map<String, Object> map : userList) {
                map.put("address", addressMap.get(map.get("id")));
            }
        }
        
        return userList;
    }

}
View Code

 

参考API

Callable<V>

Future<V>

ExecutorService.submit(java.util.concurrent.Callable)

InterruptedException

ExecutionException

 

在 Python 中,多线程并不能直接返回值。因为线程是并行执行的,所以它们之间无法直接共享变量或返回值。如果你需要获取线程执行的结果,可以使用以下方法之一: 1. 使用共享变量:你可以在主线程中创建一个共享变量,在子线程中对其进行修改,并在主线程中等待子线程完成后获取该变量的值。这可以通过 `threading` 模块的 `Thread` 类和共享变量(如 `Queue`)实现。 下面是一个示例代码: ```python import threading def worker(result): # 在子线程中修改共享变量 result.append("Hello from worker") # 创建共享变量 result = [] # 创建线程对象 thread = threading.Thread(target=worker, args=(result,)) # 启动线程 thread.start() # 等待线程结束 thread.join() # 输出共享变量的值 print(result) ``` 2. 使用回调函数:你可以定义一个回调函数,将其作为参数传递给子线程,并在子线程中调用该回调函数来传递结果。这需要通过自定义的方式来实现。 下面是一个示例代码: ```python import threading def worker(callback): result = "Hello from worker" callback(result) def on_result(result): print(result) # 创建线程对象,传递回调函数 thread = threading.Thread(target=worker, args=(on_result,)) # 启动线程 thread.start() # 等待线程结束 thread.join() ``` 请注意,在多线程编程中,对共享变量的访问需要进行适当的同步,以防止竞争条件和数据不一致的情况发生。可以使用锁(`Lock`)或其他同步机制来确保线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值