当前位置:   article > 正文

springboot快速实现多线程执行

springboot快速实现多线程执行

springboot实现多线程有多种方法,这里介绍几个实用的

1. java版,适用于快速实现【非线程池版】

首先创建一个java文件:

NewThread.java


@Slf4j
public class NewThread implements Runnable {
	public void download(String dir , String file){

		//业务内容


	}

	@Override
	public void run() {


//		System.out.println("开启了一个新线程");
//可以按顺序运行内容,也可以直接运行内部的内容;直接运行内部内容的时候run()会优先运行
//		download(file);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

然后在
controller
当中运行内部程序【因为需要传参】,多个请求可以在new Thread当中机型for循环
执行方式为按照for循环顺序执行

			NewThread newThread = new NewThread();
			newThread.download(dir,photoUrl);
			Thread thread = new Thread(newThread);
			//thread.setName("downloads");
			thread.start();

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

简版:【直接运行run方法,没有任何传参】

			NewThread newThread = new NewThread();
			Thread thread = new Thread(newThread);
			thread.start();
  • 1
  • 2
  • 3

优点:每个内容顺序执行,不会出现极高并发,访问网站和云资源的时候,不容易被识别、封号
缺点:在线程完全运行结束之前,不会给接口返回结果,前台提交请求后长时间不会得到回复

2. springboot版-多线程,默认配置-无返回,无线程数量限制

实现类:Impl:

@Slf4j
@Service
@DS("master")
public class GetImgServiceImpl extends ServiceImpl<xxxxxxMapper, 实体类> implements xxxxxxxService {

	@Async
	@Override
	public void getImg(String photoUrl, JSONObject jsonObject) throws IOException, ParseException {
//业务内容
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

重点在于在实现类当中使用

@Async
@Override
  • 1
  • 2

controller:

	for (int i = 0; i <newans.size() ; i++) {
		xxxxxxxService .getImg(photoUrl,jsonObject);
		}
  • 1
  • 2
  • 3

优点:轻松跑出几百线程;
缺点,对于对方服务器压力巨大。

执行效果:线程编号瞬间达到120+,然后纷纷结束。(并不是按照发起的顺序结束的)
在这里插入图片描述

3. springboot版-多线程,带配置-无返回,有 线程数量限制

新建配置类,重点在于@Bean的名字,如果只有一个线程池则可以不写

@Configuration
@EnableAsync
public class AsyncConfigurer {

	@Bean("normalThreadPool")  //线程池实例名,多个线程池配置需要声明,一个线程池可有可无
	public ThreadPoolTaskExecutor executor(){
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		//配置核心线程数
		executor.setCorePoolSize(15);
		//配置最大线程数
		executor.setMaxPoolSize(30);
		//配置队列大小
		executor.setQueueCapacity(10000);
		//线程的名称前缀
		executor.setThreadNamePrefix("normalThreadPool-");
		//线程活跃时间(秒)
		//executor.setKeepAliveSeconds(60);
		//等待所有任务结束后再关闭线程池
		executor.setWaitForTasksToCompleteOnShutdown(true);
		//设置拒绝策略
		//executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		//执行初始化
		executor.initialize();
		return executor;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

controller:正常不变即可

	for (int i = 0; i <newans.size() ; i++) {
		xxxxxxxService .getImg(photoUrl,jsonObject);
		}
  • 1
  • 2
  • 3

Impl:重点在于@Async("normalThreadPool")里面的名字

	@Async("normalThreadPool") //多个线程池配置时需指定配置实例
	@Override
	public void getImgLimit(String photoUrl, JSONObject jsonObject) throws IOException, ParseException {

	//业务内容
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

执行效果:控制在15个线程左右。
在这里插入图片描述

4. springboot版-多线程,带配置-有返回,有 线程数量限制

由于返回后get方法会有阻塞,所以一般使用数据库或者redis进行存储,来达到能够浏览进度的效果
Impl:

	@Async("normalThreadPool")
    public CompletableFuture<String> task() {
		String result = "";
	return CompletableFuture.completedFuture(result);
  • 1
  • 2
  • 3
  • 4

controller:

		CompletableFuture<String> result = taskService.task();
 
        log.info("result:{}", result.get()); // get 方法会使主线程阻塞
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/334303
推荐阅读
相关标签
  

闽ICP备14008679号