目前,我们的某个应用中有2个线程池:
需要设置两个不同的池来自以下思路:如果几个计划任务在主(第一)池中排队,并且它在同一池中触发它的子任务(并行处理),这将导致一场比赛条件也将排在其他计划任务的“后面”,所以什么都不会实际结束并发生死锁。
如果子任务的优先级高于计划任务,该怎么办?他们会“跳”队列并暂停计划任务以完成吗?或者那不会发生?有没有办法强迫这种行为?或者当ThreadPoolExecutor已经运行它们时,无法暂停任务?
池1在Spring的应用程序上下文XML配置文件中定义为:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="cl.waypoint.mailer.reportes" />
<task:annotation-driven scheduler="myScheduler" />
<task:scheduler id="myScheduler" pool-size="2" />
<aop:aspectj-autoproxy />
</beans>
池2在代码中定义如下:
public static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 30, TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(), new ThreadFactory() {
final AtomicLong count = new AtomicLong(0);
private String namePreffix = "TempAndDoor";
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(false);
t.setPriority(Thread.NORM_PRIORITY);
t.setName(MessageFormat.format("{0}-{1}", namePreffix, count.getAndIncrement()));
return t;
}
});
答案 0 :(得分:2)
如果我理解正确 myScheduler (pool1)用于安排任务,一旦启动任务,就会将任务提交给 executor (pool2)。
给出问题
如果子任务的优先级高于计划任务,该怎么办?
不清楚你如何区分它们或你真正的意思,但我理解的是子任务是计划任务。
我认为你应该有一些代码:
@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
executor.submit(aTaskThatRunsInParallelOrWhatYouCallASubTask);
}
其中executor是你创建的静态对象。(不应该是全部大写和最终的;)
根据其长名称,您向执行人提交的内容是“子任务”或执行者唤醒提交的任务。在这种情况下,你的myScheduler会及时唤醒,因为执行的是非阻塞的。
另一方面,由于您有一个LinkedBlockingDeque,这意味着按顺序执行,您的 执行程序 可能会被备份。
另一个问题:
他们会“跳”队列并暂停计划任务以完成吗?
他们不会跳,调度员开始,提交新任务并再次休眠。队列开始填满
下一个问题:
有没有办法强迫这种行为?或者当ThreadPoolExecutor已经运行它们时,无法暂停任务?
你可以一起取消任务,但是你将跟踪所有提交的任务
你可以抓住未来
Future aFuture = executor.submit(aTaskThatRunsInParallelOrWhatYouCallASubTask);
以某种方式你需要知道你真的要取消任务,你需要调用
aFuture.cancel();
看起来你需要的是更多参与,我建议看看非常成熟的JMS或可能更容易掌握的AKKA。