赞
踩
首先创建一个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); } }
然后在
controller
当中运行内部程序【因为需要传参】,多个请求可以在new Thread
当中机型for循环
执行方式为按照for循环顺序执行
NewThread newThread = new NewThread();
newThread.download(dir,photoUrl);
Thread thread = new Thread(newThread);
//thread.setName("downloads");
thread.start();
简版:【直接运行run方法,没有任何传参】
NewThread newThread = new NewThread();
Thread thread = new Thread(newThread);
thread.start();
优点:每个内容顺序执行,不会出现极高并发,访问网站和云资源的时候,不容易被识别、封号
缺点:在线程完全运行结束之前,不会给接口返回结果,前台提交请求后长时间不会得到回复
实现类: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 {
//业务内容
}
}
重点在于在实现类当中使用
@Async
@Override
controller:
for (int i = 0; i <newans.size() ; i++) {
xxxxxxxService .getImg(photoUrl,jsonObject);
}
优点:轻松跑出几百线程;
缺点,对于对方服务器压力巨大。
执行效果:线程编号瞬间达到120+,然后纷纷结束。(并不是按照发起的顺序结束的)
新建配置类,重点在于@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; } }
controller:正常不变即可
for (int i = 0; i <newans.size() ; i++) {
xxxxxxxService .getImg(photoUrl,jsonObject);
}
Impl:重点在于@Async("normalThreadPool")
里面的名字
@Async("normalThreadPool") //多个线程池配置时需指定配置实例
@Override
public void getImgLimit(String photoUrl, JSONObject jsonObject) throws IOException, ParseException {
//业务内容
}
执行效果:控制在15个线程左右。
由于返回后get方法会有阻塞,所以一般使用数据库或者redis进行存储,来达到能够浏览进度的效果
Impl:
@Async("normalThreadPool")
public CompletableFuture<String> task() {
String result = "";
return CompletableFuture.completedFuture(result);
controller:
CompletableFuture<String> result = taskService.task();
log.info("result:{}", result.get()); // get 方法会使主线程阻塞
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。