缘由
记录日志录入数据库时,脱离主线程,实现异步插入,这样不会拖延主线程的执行时间
ps:记录日志,可以写在业务逻辑中,也可以利用aop自动记录。
... service{
public void login(){
// 登录逻辑
......
// 记录日志插入数据库
// 这个记录过程是要占用当前线程时间的
// 通过异步线程执行,可以摆脱这种时间的消耗
logService.loginInfo(userInfo);
}
}
步骤
1.配置线程池
2.自定义一个异步任务管理器
3.自定义任务
4.指定地点处,调用执行任务管理器,传入指定的任务
/**
* 配置线程池
* /
@Configuration
public class ThreadPoolConfig
{
// 核心线程池大小
private int corePoolSize = 50;
/**
* 创建线程池
* 它继承了ThreadPoolExecutor,也就是说它也是个线程池
* 调用它,他会去线程池中拿取一个线程来执行你装入的自定义任务
* schedule使它能够提供一些周期任务和延迟任务相关的操作 *
* 相关文档
* https://blog.csdn.net/nuannuanwfm/article/details/90573943
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService()
{
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
{
@Override
protected void afterExecute(Runnable r, Throwable t)
{
super.afterExecute(r, t);
// 这里是自定义的用于日志记录线程任务执行情况的方法
Threads.printException(r, t);
}
};
}
}
注:存在多种不同类型的线程池。
最基础的线程池:ThreadPoolTaskExecutor
常用线程池:FixedThreadPool,CachedThreadPool,ScheduledThreadPool、SingleThreadExecutor
/**
* 自定义异步任务管理器
* /
public class AsyncManager
{
/**
* 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;
/**
* 这里获取上面配置的线程池
*/
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/**
* 单例模式
*/
private AsyncManager(){}
private static AsyncManager me = new AsyncManager();
public static AsyncManager me()
{
return me;
}
/**
* 执行任务
*
* @param task 任务
*/
public void execute(TimerTask task)
{
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
/**
* 停止任务线程池
*/
public void shutdown()
{
Threads.shutdownAndAwaitTermination(executor);
}
}
/**
* 自定义任务
* 注意他们返回的是TimerTask,供线程池ScheduledThreadPoolExecutor调用
* /
public class AsyncFactory
{
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
/**
* 自定义的任务-记录登陆信息
*/
public static TimerTask recordLogininfor(final String username, final String status, final String message,
final Object... args)
{
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
return new TimerTask()
{
@Override
public void run()
{
......
// 插入日志数据
SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
}
};
}
/**
* 自定义的任务-操作日志记录
*/
public static TimerTask recordOper(final SysOperLog operLog)
{
return new TimerTask()
{
@Override
public void run()
{
// 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
}
};
}
}
版权声明:本文为DX_dixi原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。