千萬數據積壓,用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快速封裝多線程,處理效率的確很高


分享到:


相關文章: