首先,实现两个UserService和AsyncUserService两个服务接口:
package com.example.demospringboot.service;
public interface UserService {
void checkUserStatus();
}
package com.example.demospringboot.service.impl;
import com.example.demospringboot.bean.User;
import com.example.demospringboot.service.UserService;
import com.example.demospringboot.dao.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void checkUserStatus() {
List<User> AllUsers = userMapper.findAllUsers();
for (User u : AllUsers) {
// System.out.println(ThreadUtils.getThreadName() + ": " + u);
log.info("{}", u);
}
};
}
package com.example.demospringboot.service;
public interface AsyncUserService {
void checkUserStatus();
}
package com.example.demospringboot.service.impl;
import com.example.demospringboot.task.AsyncTasks;
import com.example.demospringboot.service.AsyncUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AsyncUserServiceImpl implements AsyncUserService {
@Autowired
private AsyncTasks asyncTasks;
@Override
public void checkUserStatus() {
asyncTasks.doTaskOne("1");
asyncTasks.doTaskOne("2");
asyncTasks.doTaskOne("3");
};
}
然后用两个WorkManager进行管理:
package com.example.demospringboot.workmanager;
import com.example.demospringboot.service.UserService;
import com.example.demospringboot.utils.ThreadUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class WorkManager {
private static final ThreadPoolTaskExecutor EXECUTOR_POOL =
ThreadUtils.getThreadPool(ThreadUtils.EXECUTOR_POOL_PREFIX);
@Autowired
private UserService userService;
public void startExecutor() {
EXECUTOR_POOL.execute(new Executor(userService));
}
static class Executor implements Runnable {
private UserService userService;
public Executor(UserService userService) {
this.userService = userService;
}
@Override
public void run() {
while (true) {
userService.checkUserStatus();
// sleep 1s
ThreadUtils.sleepUtil(1000L);
}
}
}
}
package com.example.demospringboot.workmanager;
import com.example.demospringboot.service.AsyncUserService;
import com.example.demospringboot.utils.ThreadUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class AsyncWorkManager {
private static final ThreadPoolTaskExecutor ASYNC_EXECUTOR_POOL =
ThreadUtils.getThreadPool(ThreadUtils.ASYNC_EXECUTOR_POOL_PREFIX);
@Autowired
private AsyncUserService asyncUserService;
public void startSyncExecutor() {
ASYNC_EXECUTOR_POOL.execute(new AsyncExecutor(asyncUserService));
}
static class AsyncExecutor implements Runnable {
private AsyncUserService asyncUserService;
public AsyncExecutor(AsyncUserService asyncUserService) {
this.asyncUserService = asyncUserService;
}
@Override
public void run() {
while (true) {
asyncUserService.checkUserStatus();
// sleep 1s
ThreadUtils.sleepUtil(1000L);
}
}
}
}
用到的task类和thread工具类如下:
package com.example.demospringboot.task;
import com.example.demospringboot.utils.ThreadUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Component
public class AsyncTasks {
public static Random random = new Random();
// @Async注解中的参数就是异步任务的线程池
@Async("taskExecutor")
public CompletableFuture<String> doTaskOne(String taskNo){
log.info("开始任务:{}", taskNo);
long start = System.currentTimeMillis();
ThreadUtils.sleepUtil(random.nextInt(10000));
long end = System.currentTimeMillis();
log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start);
return CompletableFuture.completedFuture("任务完成");
}
}
package com.example.demospringboot.utils;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Repository;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
@Repository
public class ThreadUtils {
public static final int MAX_POOL_SIZE = 2;
public static final String EXECUTOR_POOL_PREFIX = "exe-" + MAX_POOL_SIZE + "-";
public static final String ASYNC_EXECUTOR_POOL_PREFIX = "async-exe-" + MAX_POOL_SIZE + "-";
public static final String ASYNC_TASK_POOL_PREFIX = "async-task-" + MAX_POOL_SIZE + "-";
// 自定义AsyncTask线程池
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(MAX_POOL_SIZE);
executor.setMaxPoolSize(MAX_POOL_SIZE);
executor.setQueueCapacity(MAX_POOL_SIZE);
executor.setKeepAliveSeconds(0);
executor.setThreadNamePrefix(ASYNC_TASK_POOL_PREFIX);
// 如果添加到线程池失败,那么主线程会自己去执行该任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
// 启动Executor的线程池
public static ThreadPoolTaskExecutor getThreadPool(String threadNamePrefix) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(MAX_POOL_SIZE);
executor.setMaxPoolSize(MAX_POOL_SIZE);
executor.setQueueCapacity(MAX_POOL_SIZE);
executor.setKeepAliveSeconds(0);
executor.setThreadNamePrefix(threadNamePrefix);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
public static void sleepUtil(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
主类如下:
package com.example.demospringboot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.cache.annotation.EnableCaching;
import com.example.demospringboot.workmanager.WorkManager;
import com.example.demospringboot.workmanager.AsyncWorkManager;
@EnableCaching
@EnableAsync
@SpringBootApplication
@MapperScan(value = {"com.example.demospringboot.dao"})
public class DemospringbootApplication implements CommandLineRunner {
@Autowired
private WorkManager workManager;
@Autowired
private AsyncWorkManager asyncWorkManager;
public static void main(String[] args) {
SpringApplication.run(DemospringbootApplication.class, args);
}
@Override
public void run(String... strings) {
//workManager.startExecutor();
asyncWorkManager.startSyncExecutor();
}
}