第一步,先定義一個(gè)線程池
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;
/**
* 自定義一個(gè)線程池
*
* @author LarryKoo (larrykoo@126.com)
* @date 2017/12/25 14:21
* @slogon 站在巨人的肩膀上
* @since 1.0.0
*/
@EnableAsync
@Configuration
public class TaskPoolConfig {
/**
* 聲明一個(gè)線程池
*
* @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)建一個(gè)需要執(zhí)行方法類
一定要將線程執(zhí)行方法單獨(dú)放置一個(gè)Class是因?yàn)?,使用?AOP,線程池配置通過(guò)注解掃描配置;所以不許要有依賴注入的動(dòng)作,才會(huì)觸發(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ù),無(wú)返回結(jié)果
*
* @param data
*/
@Async("taskExecutor")
public void doTaskOne(String data) {
try {
log.info("開(kāi)始做任務(wù)1");
Stopwatch sw = Stopwatch.createStarted();
Thread.sleep(5000);
log.info("完成任務(wù)1, 耗時(shí):{}", sw.stop());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 有返回結(jié)果,通過(guò) AsyncResult 異步獲取
*
* @param data
* @return
*/
@Async("taskExecutor")
public Future<String> doTaskTwo(String data) {
try {
log.info("開(kāi)始做任務(wù)2");
Stopwatch sw = Stopwatch.createStarted();
Thread.sleep(5000);
log.info("完成任務(wù)2, 耗時(shí):{}", sw.stop());
return new AsyncResult<>(data);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
第三步,執(zhí)行 run 方法,詳細(xì)的單元測(cè)試
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;
/**
* 單元測(cè)試
*
* @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("開(kāi)始請(qǐng)求任務(wù)1");
Stopwatch sw = Stopwatch.createStarted();
simpleTask.doTaskOne("12345");
log.info("完成請(qǐng)求任務(wù)1, 耗時(shí):{}", sw.stop());
}
@Test
public void testRunTaskTwo() throws ExecutionException, InterruptedException {
log.info("================= run_task_two =======================");
log.info("開(kāi)始請(qǐng)求任務(wù)2");
Stopwatch sw = Stopwatch.createStarted();
Future<String> feature = simpleTask.doTaskTwo("12345");
while (true) {
if (feature.isDone()) {
log.info("完成請(qǐng)求任務(wù)2,返回結(jié)果:{}, 耗時(shí):{}", feature.get(), sw.stop());
break;
}
}
}
@Test
public void testRunTaskTwoPlus() throws ExecutionException, InterruptedException, TimeoutException {
log.info("================= run_task_two_plus =======================");
log.info("開(kāi)始請(qǐng)求任務(wù)2");
Stopwatch sw = Stopwatch.createStarted();
Future<String> feature = simpleTask.doTaskTwo("12345");
String result = feature.get(10, TimeUnit.SECONDS);
log.info("完成請(qǐng)求任務(wù)2,返回結(jié)果:{}, 耗時(shí):{}", result, sw.stop());
}
}
源代碼參考提供
以上實(shí)例見(jiàn)源代碼:https://github.com/gumutianqi/springboot2-learn/tree/master/spring-boot2-threadpool