Spring TaskExecutor实现队列优先级

时间:2018-05-28 15:27:28

标签: java spring queue executor

我正在处理的应用程序接收来自外部系统的通知,我想要处理这些通知。

直到现在我有以下实施:

    public class AsynchronousServiceImpl implements AsynchronousService {

    private TaskExecutor taskExecutor;

    @Override
    public void executeAsynchronously(Runnable task) {
        taskExecutor.execute(task);
    }

    @Required
    public void setTaskExecutor(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }
}

spring配置(我只需要1个线程,因为我不想并行执行通知,因为一些难以改变的遗留问题)

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="1"/>
    <property name="maxPoolSize" value="1"/>
    <property name="WaitForTasksToCompleteOnShutdown" value="true"/>
</bean>

然后我执行代码:

 asynchronousService.executeAsynchronously(new Runnable() {
     @Override
     public void run() {
         someMethod.processNotification(notification)
      }
   });

我的Notification对象包含一个时间戳字段。 我想通过这个字段优先处理队列中的通知(我认为Spring使用默认的无界队列,这对我来说更好,因为我需要一个无界的队列)

我可以在春季应用程序中以某种方式将其集成,而无需从头开始手动实现吗?所以我想根据通知对象上的timestamp字段对队列中的taskss(runnable-objects)进行排序。(我将这个对象传递给“processNotification”方法)

1 个答案:

答案 0 :(得分:2)

ThreadPoolTaskExecutorBlockingQueue支持:

protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
    if (queueCapacity > 0) {
        return new LinkedBlockingQueue<Runnable>(queueCapacity);
    }
    else {
        return new SynchronousQueue<Runnable>();
    }
}

如果要订购任务,则需要覆盖此功能以允许优先级排序:

public class YourPool extends ThreadPoolTaskExecutor {
    @Override
    protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
        return new PriorityBlockingQueue<>(queueCapacity);
    }
}

您提交的任务必须具有可比性:

public class YourTask implements Runnable, Comparable<YourTask> {
    private Notification notification;

    public YourTask(Notification notification) {
        this.notification = notification;
    }
    @Override
    public void run() {
        someMethod.processNotification(notification)
    }

    @Override
    public int compareTo(B other) {
        // Here you implement the priority
        return notification.getTimestamp().compareTo(other.notification.getTimestamp());
    }
}

然后提交你的任务:

asynchronousService.executeAsynchronously(new YourTask(notificationX));