第一步,先定義一個線程池
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.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 自定義一個線程池
*
* @author LarryKoo (larrykoo@126.com)
* @date 2017/12/25 14:21
* @slogon 站在巨人的肩膀上
* @since 1.0.0
*/
@EnableAsync
@Configuration
public class TaskPoolConfig {
/**
* 聲明一個線程池
*
* @return
*/
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(1000);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("taskExecutor-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(10);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
第二步,創(chuàng)建一個需要執(zhí)行方法類
一定要將線程執(zhí)行方法單獨放置一個Class是因為舆乔,使用了 AOP磨德,線程池配置通過注解掃描配置缘回;所以不許要有依賴注入的動作,才會觸發(fā)調(diào)用線程池的配置典挑;不要忘了哦酥宴!
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;
/**
* SimpleTask
*
* @author LarryKoo (larrykoo@126.com)
* @date 2017/12/25 14:21
* @slogon 站在巨人的肩膀上
* @since 1.0.0
*/
@Slf4j
@Component
public class SimpleTask {
/**
* 普通任務(wù),無返回結(jié)果
*
* @param data
*/
@Async("taskExecutor")
public void doTaskOne(String data) {
try {
log.info("開始做任務(wù)1");
Stopwatch sw = Stopwatch.createStarted();
Thread.sleep(5000);
log.info("完成任務(wù)1您觉, 耗時:{}", sw.stop());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 有返回結(jié)果拙寡,通過 AsyncResult 異步獲取
*
* @param data
* @return
*/
@Async("taskExecutor")
public Future<String> doTaskTwo(String data) {
try {
log.info("開始做任務(wù)2");
Stopwatch sw = Stopwatch.createStarted();
Thread.sleep(5000);
log.info("完成任務(wù)2, 耗時:{}", sw.stop());
return new AsyncResult<>(data);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
第三步琳水,執(zhí)行 run 方法肆糕,詳細的單元測試
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import me.weteam.threadpool.task.SimpleTask;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* 單元測試
*
* @author LarryKoo (larrykoo@126.com)
* @date 2018/08/03 14:21
* @slogon 站在巨人的肩膀上
* @since 1.0.0
*/
@Slf4j
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ThreadTestCase {
@Autowired
private SimpleTask simpleTask;
@Test
public void testRunTaskOne() {
log.info("================= run_task_one =======================");
log.info("開始請求任務(wù)1");
Stopwatch sw = Stopwatch.createStarted();
simpleTask.doTaskOne("12345");
log.info("完成請求任務(wù)1, 耗時:{}", sw.stop());
}
@Test
public void testRunTaskTwo() throws ExecutionException, InterruptedException {
log.info("================= run_task_two =======================");
log.info("開始請求任務(wù)2");
Stopwatch sw = Stopwatch.createStarted();
Future<String> feature = simpleTask.doTaskTwo("12345");
while (true) {
if (feature.isDone()) {
log.info("完成請求任務(wù)2,返回結(jié)果:{}在孝, 耗時:{}", feature.get(), sw.stop());
break;
}
}
}
@Test
public void testRunTaskTwoPlus() throws ExecutionException, InterruptedException, TimeoutException {
log.info("================= run_task_two_plus =======================");
log.info("開始請求任務(wù)2");
Stopwatch sw = Stopwatch.createStarted();
Future<String> feature = simpleTask.doTaskTwo("12345");
String result = feature.get(10, TimeUnit.SECONDS);
log.info("完成請求任務(wù)2诚啃,返回結(jié)果:{}, 耗時:{}", result, sw.stop());
}
}
源代碼參考提供
以上實例見源代碼:https://github.com/gumutianqi/springboot2-learn/tree/master/spring-boot2-threadpool