千万数据积压,用Spring快速封装多线程,处理效率的确很高

工作中常常会出现,数据处理积压的情况,这个时候就会用到多线程,提高并发处理任务的能力。

线程是进程中执行运算的最小单位,进程是表示资源分配的基本单位,多线程代表一个程序进程下通过程序控制开启多个线程任务类。

java的jdk中已经分装好了多线程模块,实现多线程的方式有两种,一种是通过继承 Thread 类,另一种是通过实现 Runnable 接口。使用继承 Thread 类创建多线程,最大的缺点就是不能多继承,所以为了支持多继承,完全可以实现 Runnable 接口的方式。需要说明的是,这两种方式在工作时的性质都是一样的,没有本质的区别。

不过本文主要说明Spring快速搭建多线程

Spring是通过任务执行类( TaskExecutor )来实现多线程和并发编程

使用ThreadPoolTaskExecutor可以实现一个基于线程池的TaskExecutor,而实际开发中任务一般是异步的,所以通常会通过@EnableAsync注解开启异步任务的开关

执行任务类


千万数据积压,用Spring快速封装多线程,处理效率的确很高

<code>package lt;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
@Configuration@ComponentScan("lt")
@EnableAsync //异步任务注解开关//配置类实现AsyncConfigurer接口并重写getAsyncExecutor方法public class ExecutorTaskConfig implements AsyncConfigurer {
//通过重写得基于线程池的TaskExecutor @Override public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);//线程池维护线程的最少数量  taskExecutor.setMaxPoolSize(200);//线程池维护线程的最大数量 taskExecutor.setQueueCapacity(25);//线程池所使用的缓冲队列 taskExecutor.initialize();
return taskExecutor;
}

@Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}/<code>

备注:

利用@EnableAsync注解开启异步任务支持。

业务处理类

通过@Async这个注解,如果注解在类级别,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor.


千万数据积压,用Spring快速封装多线程,处理效率的确很高

备注:

配置类实现AsyncConfigurer接口并重写getAsyncExecutor方法,并返回一ThreadPoolTaskExecutor ,这样我们就获得了一个基于线程池TaskExecutor

<code>package lt;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;

@Servicepublic class TaskAsyncService {
//这个注解代表方法是异步的,如果注解写到类上代表类的所有方法都是异步方法, @Async public void executeAsyncTask(Integer i){
System.out.println(new Date().getSeconds()+"秒执行任务: "+i);
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(new Date().getSeconds()+"秒执行完毕: "+i);
}

@Async public void executeAsyncTaskPlus(Integer i){
System.out.println(new Date().getSeconds()+"秒执行乘法任务: "+(i*10));
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(new Date().getSeconds()+"秒执行乘法完毕: "+(i*10));
}

public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(ExecutorTaskConfig.class);

TaskAsyncService asyncTaskService = context.getBean(TaskAsyncService.class);

for(int i =1 ;i<5;i++){
asyncTaskService.executeAsyncTask(i);
asyncTaskService.executeAsyncTaskPlus(i);
}
context.close();
}
}/<code>

通过结果可以分析出是并发执行而不是顺序执行的


千万数据积压,用Spring快速封装多线程,处理效率的确很高


分享到:


相關文章: