版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vbirdbest/article/details/82346655
一:简介
ThreadPoolTaskExecutor 用于定义线程池,是对java.util.concurrent.ThreadPoolExecutor类的包装。可以通过@EnableAsync来开启异步支持,通过@Async来声明一个异步方法
二:示例
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
/**
* 定义线程池
* @return
*/
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
/**
* 异步方法抛出异常时处理器
* return null: 使用默认的处理器,打印异常信息和堆栈
* 也可以自定义自己的异常处理器
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
// return new MyAsyncUncaughtExceptionHandler();
}
/**
* 自定义异常处理
* 没有返回值的异步方法当抛异常时会走AsyncUncaughtExceptionHandler
*/
class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
System.out.println("Exception message - " + throwable.getMessage());
System.out.println("Method name - " + method.getName());
for (Object param : objects) {
System.out.println("Parameter value - " + param);
}
}
}
}
注意:异步方法的调用和异步方法的声明必须不能在同一个类中,如果在同一个类中则变成了同步方法
@Service
public class AsyncTaskService {
/**
* 无参无返回值
*/
@Async
public void executeAsyncTask1() {
for (int i = 0; i < 5; i++) {
System.out.println("executeAsyncTask1 = " + Thread.currentThread().getName() + "\t i=" + i);
try {
Thread.sleep(100);
// int a = 1/0;
} catch (InterruptedException e) { }
}
}
/**
* 有参无返回值
* @param name
*/
@Async
public void executeAsyncTask2(String name) {
for (int i = 0; i < 5; i++) {
System.out.println(name + " =\t" + Thread.currentThread().getName() + "\t i=" + i);
try { Thread.sleep(100); } catch (InterruptedException e) { }
}
}
/**
* 有返回值有参数
* 这种情况下当方法抛异常可以在方法内部处理掉异常或者在调用future.get时处理异常
* @param value
* @return
*/
@Async
public Future<String> executeAsyncTask3(String value) {
Future<String> future;
try {
Thread.sleep(100);
System.out.println(value + " =\t" + Thread.currentThread().getName());
future = new AsyncResult<>(value.toUpperCase());
} catch (InterruptedException e) {
future = new AsyncResult<String>("error");
}
return future;
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAsyncApplicationTests {
@Autowired
private AsyncTaskService asyncTaskService;
@Test
public void testAsync() throws Exception {
asyncTaskService.executeAsyncTask1();
asyncTaskService.executeAsyncTask2("AsyncTask2");
Future<String> future = asyncTaskService.executeAsyncTask3("AsyncTask3");
String result = future.get();
System.out.println("result=" + result);
Thread.sleep(3000);
}
@Test
public void testSync() throws Exception {
test();
for (int i = 0; i < 10; i++) {
System.out.println("testSync = " + Thread.currentThread().getName() + "\t i=" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
}
Thread.sleep(3000);
}
/**
* 注意:@Async要想异步,调用方法的代码和方法的声明必须在不同的类中才能异步,否则是同步
* test(); 方法的调用在SpringbootAsyncApplicationTests这个类,方法的声明也是在这个类,所以该方法实际是同步方法,并不是异步
*/
@Async
public void test() {
for (int i = 0; i < 10; i++) {
System.out.println("SpringbootAsyncApplicationTests = " + Thread.currentThread().getName() + "\t i=" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
}
}
}