Java异步任务管理器
温馨提示:
本文最后更新于 2022年06月11日,已超过 879 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
1. 什么是异步任务管理器
异步任务管理器就是一个可以快速创建异步任务的一个工具
2. 为什么要采用异步任务
提高业务系统响应速度,实现不同业务之间的解耦
2.1 举例
|
记录访客日志,发送工单等
如果系统每一步的日志记录都是伴随着业务一起执行的,那么当系统访问量增的时候,就会大大降低系统的响应速度|
因为写操作是比读操作更耗时的,如果能够做到异步的记录日志,就不必等待日志记录完成即可返回查询、搜索结果,
3. 如何实现异步任务管理器
异步任务可以通过多线程也可以通过消息队列配合定时任务来实现,但是相对于小型系统采用多线程的方式相对便捷
3.1 多线程实现异步任务
3.1.1 自定义线程池
自定义线程池实现了单例模式获取自定义线程池对象,以及通过该单例对象初始化一个线程池对象executor
MyThreadPool.java
package com.zyd.blog.framework.config;
import lombok.Data;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import java.util.concurrent.*;
/**
* @Auth: cxc
* @DATE: 2022-6-10
* 自定义线程池
*/
@Data
public class MyThreadPool {
// 自定义的线程池单例对象
private static MyThreadPool myThreadPool;
// 核心线程池大小
private static int corePoolSize = 2;
// 最大可创建的线程数
private static int maxPoolSize = 3;
// 队列最大长度
private static int queueCapacity = 1000;
// 线程池维护线程所允许的空闲时间
private static int keepAliveSeconds = 300;
// 线程池所需要一个队列来存放线程对象
private static BlockingQueue blockingQueue = new LinkedBlockingDeque(queueCapacity);
// 线程池中创建线程的名称
private String threadName;
// 真正的线程池对象
private ThreadPoolExecutor executor;
public MyThreadPool() {
}
/**
* 获取自定义线程池单例对象
* @param threadName
* @return
*/
public static MyThreadPool getInstance(String threadName) {
if (myThreadPool != null && threadName.equals(myThreadPool.threadName)) {
return myThreadPool;
}
synchronized (MyThreadPool.class) {
myThreadPool = new MyThreadPool();
myThreadPool.setThreadName(threadName);
myThreadPool.setExecutor(new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveSeconds, TimeUnit.SECONDS,blockingQueue,
new BasicThreadFactory.Builder().namingPattern(threadName+"-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy()));
}
return myThreadPool;
}
}
3.1.1 异步任务管理器
执行异步任务execute()方法
停止线程池shutdown()方法
AsyncTaskManager.jva
package com.zyd.blog.util;
import com.zyd.blog.framework.config.MyThreadPool;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.TimerTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @Auth: cxc
* @DATE: 2022-6-10
* 异步任务管理器,用于异步任务的执行
*/
@Slf4j
@Data
@Component
public class AsyncTaskManager {
// 单例模式生成异步任务管理器对象
private static AsyncTaskManager asyncTaskManager;
// 操作延迟10毫秒
private final int START_DELAY_TIME = 10;
// 获取线程池对象
private ThreadPoolExecutor executor;
private String threadName;
/**
* 获取异步任务单例对象
* 用于执行异步任务
* @return
*/
public static AsyncTaskManager getInstance(String threadName) {
if (null != asyncTaskManager && threadName.equals(asyncTaskManager.getThreadName())) {
return asyncTaskManager;
}
synchronized (AsyncTaskManager.class) {
asyncTaskManager = new AsyncTaskManager();
asyncTaskManager.setThreadName(threadName);
asyncTaskManager.setExecutor(MyThreadPool.getInstance(threadName).getExecutor());
}
return asyncTaskManager;
}
/**
* 执行异步任务
* @param task
*/
public void execute(TimerTask task) {
if (executor ==null) {
executor = MyThreadPool.getInstance("threadName").getExecutor();
}
executor.execute(task);
}
/**
* 停止任务线程池
*/
public void shutdown() {
if (executor != null && !executor.isShutdown())
{
executor.shutdown();
try
{
if (!executor.awaitTermination(120, TimeUnit.SECONDS))
{
executor.shutdownNow();
if (!executor.awaitTermination(120, TimeUnit.SECONDS))
{
log.info("Pool did not terminate");
}
}
}
catch (InterruptedException ie)
{
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
}
3.1.3 异步工厂
用于定义各种异步任务
AsyncFactory.java
package com.zyd.blog.util;
import lombok.extern.slf4j.Slf4j;
import java.util.TimerTask;
/**
* @Auth: cxc
* @DATE: 2022-6-11
*/
@Slf4j
public class AsyncFactory {
public static TimerTask insertSerachRecord(String name,String result) {
return new TimerTask() {
@Override
public void run() {
log.info("{}搜索了{}",name,result);
}
};
}
public static TimerTask writerLog(String name,String result) {
return new TimerTask() {
@Override
public void run() {
log.info("{}访问了{}",name,result);
}
};
}
}
3.1.4 测试
CommonTest.java
package com.zyd.blog;
import com.zyd.blog.util.AsyncFactory;
import com.zyd.blog.util.AsyncTaskManager;
import java.util.TimerTask;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Auth: cxc
* @DATE: 2022-6-11
*/
public class CommonTest {
public static void main(String[] args) throws InterruptedException {
AsyncTaskManager.getInstance("记录日志").execute(AsyncFactory.insertSerachRecord("杨幂","我的博客"));
AsyncTaskManager.getInstance("搜索记录").execute(AsyncFactory.insertSerachRecord("杨幂","小陈没烦恼"));
AsyncTaskManager.getInstance("记录日志").execute(AsyncFactory.insertSerachRecord("柳岩","主页"));
AsyncTaskManager.getInstance("记录日志").execute(AsyncFactory.insertSerachRecord("柳岩","我爱你"));
Thread.sleep(10000);
System.out.println("主线程结束!");
}
}
3.1.5 运行结果
正文到此结束
- 本文标签: Java 多线程 异步任务
- 本文链接: https://www.it1997.com/article/89
- 版权声明: 本文由小陈没烦恼原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权