背景:
当调用一些耗时接口时,如果我们一直在原地等待方法返回,整体程序的运行效率会大大降低。可以把调用的过程放到子线程去执行,再通过 Future 去控制子线程的调用过程,最后获取到计算结果。提高整个程序的运行效率。
创建线程池:
public class ExecutorConfig { private final static int THREAD_COUNT = Runtime.getRuntime().availableProcessors() * 2; name = "batchCallThreadPool") ( public ThreadPoolExecutor batchPredictThreadPool() { return new ThreadPoolExecutor(THREAD_COUNT, 200, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(2048), new ThreadFactoryBuilder().setNameFormat("batch-call-pool-%d").build()); } }
利用Future获取线程执行结果
import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import com.google.common.collect.Maps; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class FutureTestService { private CallService callService; "batchPredictThreadPool") ( private ThreadPoolExecutor batchPredictThreadPool; public void fun(List<Long> idList) { Map<Long, Future<Integer>> futureMap = Maps.newHashMapWithExpectedSize(idList.size()); // 让所有调用的子线程启动,参与竞争 for (Long id : idList) { Future<Integer> future = batchPredictThreadPool.submit(() -> callService.call(id)); futureMap.put(id, future); } for (Long id : futureMap.keySet()) { try { // 阻塞获取执行结果,如果 3s 未获取到会抛出超时异常 Integer result = futureMap.get(id).get(3000, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { // 处理超时 } catch (ExecutionException e) { // 处理执行时异常 } catch (InterruptedException e) { // 处理 中断 } } } }