java执行器服务持久队列
我实现了Spring TaskExecutor(相当于JDK1.5的Executor)来处理从外部系统接收的通知 仅与一种方法进行接口:java执行器服务持久队列,java,spring,persistence,executorservice,Java,Spring,Persistence,Executorservice,我实现了Spring TaskExecutor(相当于JDK1.5的Executor)来处理从外部系统接收的通知 仅与一种方法进行接口: public interface AsynchronousService { void executeAsynchronously(Runnable task); } 以及相应的实施: public class AsynchronousServiceImpl implements AsynchronousService { private
public interface AsynchronousService {
void executeAsynchronously(Runnable task);
}
以及相应的实施:
public class AsynchronousServiceImpl implements AsynchronousService {
private Executor taskExecutor;
@Override
public void executeAsynchronously(Runnable task) {
taskExecutor.execute(task);
}
@Required
public void setTaskExecutor(Executor taskExecutor) {
this.taskExecutor = taskExecutor;
}
}
任务执行器(遗留应用程序)的Xml配置:
我不仅希望队列在内存中,还希望任务在数据库中持久化,因此即使应用程序崩溃,我也可以使用它们
我想到的第一个解决方案是覆盖YourCustomThreadPoolExecutor
类中的默认beforeExecute
回调:
public class YourCustomThreadPoolExecutor extends ThreadPoolExecutor {
public YourCustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
// 1) serialize runnable object
// 2) write in the database (with a flag if it is executed true/false)
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
}
}
public类YourCustomThreadPoolExecutor扩展ThreadPoolExecutor{
public YourCustomThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、时间单位、BlockingQueue workQueue、ThreadFactory ThreadFactory、RejectedExecutionHandler){
super(corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler);
}
@凌驾
执行前受保护的void(线程t,可运行r){
//1)序列化可运行对象
//2)写入数据库(如果执行true/false,则带有标志)
超级执行前(t,r);
}
@凌驾
执行后受保护的无效(可运行的r、可丢弃的t){
super.afterExecute(r,t);
}
}
现在的想法是,当我执行任务时,我将首先检查数据库,如果它存在未执行的任务(例如,通过检查布尔标志)。如果是,那么我首先得到这个任务并执行它并更新标志。然后我继续执行另一个任务。因此,在本例中,如果应用程序在执行任务后崩溃,那么我仍然确保在应用程序再次运行后执行该任务,它不会丢失。你认为这个解决方案怎么样
首先,我试图找到一个钩子方法,在将任务放入队列之前调用该方法,这样我就可以在那里执行任务的存在性。(因为我更喜欢在将任务放入队列之前先体验任务),但我没有找到任何方法,这就是为什么我唯一的机会是重写
beforeExecutue
方法。这当然不是很理想,因为我只有在取消任务时才开始持久化任务,因此如果应用程序崩溃,队列中的所有任务都将丢失。如果要持久化,请在插入到队列之前保存任务Queue@Mạ新罕布什尔州奎伊ế唐古伊ễ我想实现这一点,但所有逻辑都由Executor服务处理。我想我可以修改ExecutorService来实现这一点,也许有一个钩子方法可以重写,但是我找不到任何方法。但是,在调用之前,我只是保持队列:asynchronousService.executeAsynchronously(newnotificationtask(notificationService,notification))这就是你的意思?嗨@Norbert94,你成功了吗?我对开发类似的东西很感兴趣,我认为你的反馈会很有帮助。提前谢谢!关于持久化所有排队的任务;如果您创建了一个包装器,将任务委托给执行者,但在提交之前将任务持久化,该怎么办?您还可以检查任务是否被拒绝以撤消持久性。你觉得怎么样?嗨@Ariles,我很抱歉这么晚才回答,是的,我成功了-我使用了这个解决方案:我希望这对你有帮助
public class NotificationPool extends ThreadPoolExecutorFactoryBean{
@Override
protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
return new PriorityBlockingQueue<>(queueCapacity);
}
}
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maxPoolSize, int keepAliveSeconds,
BlockingQueue<Runnable> queue, ThreadFactory threadFactory,
RejectedExecutionHandler rejectedExecutionHandler) {
return new YourCustomThreadPoolExecutor (corePoolSize, maxPoolSize, keepAliveSeconds, TimeUnit.SECONDS, queue,
threadFactory, rejectedExecutionHandler);
public class YourCustomThreadPoolExecutor extends ThreadPoolExecutor {
public YourCustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
// Here do something with your exception
}
}
public class NotificationTask implements Runnable, Comparable<NotificationTask> {
private final NotificationService notificationService;
private final Notification notification;
public NotificationService(NotificationService notificationService,
Notification notification) {
this.notificationService = notificationService;
this.notification = notification;
}
@Override
public int compareTo(NotificationTask task) {
return notification.getTimestamp().compareTo(task.getTimestamp());
}
@Override
public void run() {
notificationService.processNotification(notification);
}
}
asynchronousService.executeAsynchronously(new NotificationTask (notificationService, notification));
public class YourCustomThreadPoolExecutor extends ThreadPoolExecutor {
public YourCustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
// 1) serialize runnable object
// 2) write in the database (with a flag if it is executed true/false)
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
}
}