使用spring提供的异步包
执行对应方法
CompletableFuture.runAsync(() -> appInfSyncService.sync2Ducc(entity.getAppId()), threadPoolExecutor);
可以执行对应代码
CompletableFuture.supplyAsync(() -> {}
优点:可以让指定线程池执行指定类的指定方法(该类无需为线程相关类,该方法也无需是run或者call方法)
使用@Async("指定线程池")注解使用
@Async
public Future<String> doSomethingAsyncWithReturn() {
System.out.println("Start Async Task with Return");
try {
Thread.sleep(5000); // 模拟长时间任务
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End Async Task with Return");
//可以获取异步结果
return new AsyncResult<>("Task Completed");
}
}
Sirector异步调用
可以按照任务调度执行异步任务
异步任务需要实现EventHandler接口
Event为异步传参
EventHandler<PictureRecognitionEvent>[] pictureRecognitionHandlers
Sirector<PictureRecognitionEvent> recognitionEventSirector = new Sirector<>(imageAndPromotionRecognitionThreadPool);
recognitionEventSirector.begin(pictureRecognitionHandlers);
recognitionEventSirector.ready();
recognitionEventSirector.publish(pictureRecognitionEvent, commonConfig.getImageProRecoSirectorTimeoutConfig());
使用消息发布
在开始时使用线程池执行任务(消息队列任务)
public void afterPropertiesSet() throws Exception {
Map<String, AbstractBatchTaskService> taskServices = applicationContext.getBeansOfType(AbstractBatchTaskService.class);
if (MapUtils.isNotEmpty(taskServices)) {
for (Map.Entry<String, AbstractBatchTaskService> entry : taskServices.entrySet()) {
String beanName = entry.getKey();
AbstractBatchTaskService taskService = entry.getValue();
if (taskService.isStop()) {
log.error("task {} had stop, not register", beanName);
} else {
batchTaskExecutorService.execute(taskService);
if (log.isInfoEnabled()) {
log.info("register task {}", beanName);
}
}
}
} else {
log.error("no task shutdown batchTaskExecutorService ");
destroy();
}
}
使用线程池+阻塞队列实现
private final BlockingQueue<T> queue = new LinkedBlockingQueue<T>();
public boolean offer(T newTask) {
return queue.offer(newTask);
}
public void run() {
//死循环等待消息来即执行消息
while (true) {
List<T> curTasks = new ArrayList<T>(batchSize);
CallerInfo callerInfo = null;
try {
//第一任务不设置超时
curTasks.add(queue.take());
callerInfo = Ump.methodReg(umpKey);
long from = now();
while (curTasks.size() < batchSize && now() - from < DEFAULT_INTERVAL_MIS) {
T task = queue.poll(DEFAULT_INTERVAL_MIS / 2, TimeUnit.MILLISECONDS);
if (task != null) {
curTasks.add(task);
}
}
//如果任务达到10个,或者自从接受到第一个task过了200MS
processTask(curTasks);
curTasks.clear();
Ump.methodRegEnd(callerInfo);
} catch (Throwable e) {
Ump.funcError(callerInfo);
log.error("maybe lost data : {}", JsonUtil.write2JsonStr(curTasks), e);
}
}
}
(直接使用线程池方法执行任务)
Future<ReceiveResult> futureTask = eventProcessThreadPool.submit(new ExecutorReceiveCouponTask(channelParam, pin, uuid, couponId, couponServiceRpc));