java线程池批量异步执行方法,获取返回值

1 篇文章 0 订阅
1 篇文章 0 订阅


前言

接口里面循环调用方法,默认是同步执行,如果方法执行缓慢,循环次数较多,那么这个接口就会较长时间才能返回结果,推荐使用线程池并发异步执行


一、概念介绍

使用线程池的好处

使用线程池最大的原因就是可以根据系统的需求和硬件环境灵活的控制线程的数量,且可以对所有线程进行统一的管理和控制,从而提高系统的运行效率,降低系统运行运行压力;当然了,使用线程池的原因不仅仅只有这些,我们可以从线程池自身的优点上来进一步了解线程池的好处;

使用线程池有哪些优势

1:线程和任务分离,提升线程重用性;
2:控制线程并发数量,降低服务器压力,统一管理所有线程;
3:提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间;

CompletableFuture的理解

https://www.jianshu.com/p/abfa29c01e1d

二、使用步骤

1.配置线程池

代码如下(示例):


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Description:线程池管理
 * @author: lw
 * @date: 2018年12月17日
 */
@Configuration
@EnableAsync
public class ThreadPoolTaskExecutorConfig {
    //阻塞队列
    private static final int workQueue = 20;
    //线程空闲后的存活时长
    private static final int keepAliveTime = 30;
    //Cpu核数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    //核心线程数量大小
    private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    //线程池最大容纳线程数
    private static final int maxPoolSize = CPU_COUNT * 2 + 1;

    @Bean("asyncTaskExecutor")
    public ThreadPoolTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setThreadNamePrefix("asyncTaskExecutor-");//线程前缀
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);//核心线程数
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);//最大线程数
        threadPoolTaskExecutor.setQueueCapacity(workQueue);//等待队列
        threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveTime);//线程池维护线程所允许的空闲时间,单位为秒
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 线程池对拒绝任务(无线程可用)的处理策略
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

2.异步执行方法

代码如下(示例):

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.CompletableFuture;

@Autowired
@Qualifier("asyncTaskExecutor")
private ThreadPoolTaskExecutor threadPoolTaskExecutor;

public List<JSONObect> listResult(){
	List<JSONObect> result = new ArrayList<>();
	List<CompletableFuture<HttpResponse>> futures = new ArrayList<>();
	for (String url UrlList) {
		CompletableFuture<HttpResponse> future = CompletableFuture.supplyAsync(() -> {
					//方法处理逻辑
	                HttpResponse res = null;
	                try {
	                    res = HttpRequest.post(url)
	                            .header("Authorization", accessToken)
	                            .body(JSON.toJSONString(new JSONObject()))
	                            .execute();
	                    } catch (Exception e) {
	                        log.error(e.getMessage());
	                        if (res != null) {
	                            log.error(res.toString());
	                        }
	                    }
	                    return res;
	                }, threadPoolTaskExecutor);//指定线程池
	                
	                futures.add(future);
	                
	                try {
	                	//方法处理完成回调
	                    future.thenAccept((HttpResponse res) -> {
	                        if (res.isOk()) {
	                            String body = res.body();
	                            if (JSONValidator.from(body).validate()) {
	                                JSONObject dataJSON = JSON.parseObject(body);
	                                if (dataJSON.containsKey("data")) {
	                                    if (!ObjectUtils.isEmpty(dataJSON.get("data"))) {
	                                        result.add(dataJSON.get("data"));
	                                    }
	                                }
	                            }
	                        }
	                    });
	                } catch (Exception e) {
	                    log.error(e.getMessage());
	                }
	     
	}
	//等待所有线程执行完毕
	CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]))
	        .whenComplete((v, th) -> {
	            log.info("所有任务执行完成触发");
	        }).join();
     //返回结果
	return result;
}

总结

本内容仅是对配置线程池和指定线程池的异步并发执行
使用的时候一定要先理解再使用,勿在浮沙筑高台

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java线程池可以很好地管理和调度多线程任务,实现异步任务。以下是一个简单的示例,演示如何使用Java线程池实现异步任务: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AsyncTasks { private ExecutorService executorService = Executors.newFixedThreadPool(10); public void runAsyncTask(Runnable task) { executorService.execute(task); } } ``` 在上面的代码中,我们创建了一个名为`AsyncTasks`的类,该类具有一个`ExecutorService`对象,用于管理我们的线程池。我们还定义了一个`runAsyncTask`方法,该方法接受一个`Runnable`对象作为参数,并将其提交给线程池进行异步执行。 要使用这个类,我们可以创建一个新的异步任务并将其传递给`runAsyncTask`方法。例如: ```java public class Main { public static void main(String[] args) { AsyncTasks asyncTasks = new AsyncTasks(); // 创建一个新的异步任务 Runnable task = new Runnable() { @Override public void run() { // 执行异步任务 System.out.println("Async task is running."); } }; // 提交异步任务到线程池 asyncTasks.runAsyncTask(task); } } ``` 在这个例子中,我们首先创建了一个`AsyncTasks`对象,然后创建了一个新的`Runnable`对象,该对象包含了我们想要在异步任务中执行的代码。最后,我们将这个`Runnable`对象传递给`runAsyncTask`方法,该方法将任务提交给线程池进行异步执行。 使用Java线程池实现异步任务可以提高程序的并发性和响应性,并且可以有效地管理和调度多线程任务。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值