java - 处理线程池中的优先级

标签 java multithreading threadpool priority-queue thread-priority

目前,我们的一个应用程序中有 2 个线程池:

  1. 第一个是用于处理计划任务的
  2. 第二个涉及并行处理正在运行的每个计划任务

需要设置两个不同的池来自以下想法:如果多个计划任务在主(第一个)池中排队,并且它触发同一池中的子任务(并行处理),这将导致竞争条件 as 也会在其他计划任务“后面”排队,因此实际上什么都不会结束,并且会发生死锁。

如果子任务的优先级高于计划任务怎么办?他们会“插队”并暂停计划任务以完成任务吗?或者这不会发生?有什么方法可以强制这种行为吗?或者当 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;
            }
        });

最佳答案

如果我理解正确的话myScheduler(pool1)用于安排任务,一旦时间开始,它就会将任务提交给执行器 (池2)。

给出问题

如果子任务的优先级高于计划任务怎么办?

不清楚如何区分它们或您的真正含义,但我的理解是子任务是计划任务。

我认为你应该有一些类似的代码:

@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
    executor.submit(aTaskThatRunsInParallelOrWhatYouCallASubTask);
}

其中 executor 是您要在其中创建的静态对象。(不应该全部大写和结尾;))

根据其长名称,您提交给执行器的内容是“子任务”或执行器唤醒提交的任务。在这种情况下,您的 myScheduler 将始终及时唤醒,因为执行的内容是非阻塞的。

另一方面,由于您有一个 LinkedBlockingDeque,这意味着按顺序执行,因此您的执行器可能会得到备份。

另一个问题:

他们会“跳过”队列并暂停计划任务以完成任务吗?

它们不会跳跃,调度程序启动,提交新任务并再次 hibernate 。队列开始变满

下一个问题:

有什么方法可以强制这种行为吗?或者当 ThreadPoolExecutor 已经在运行任务时,任务无法暂停?

您可以一起取消任务,但您将跟踪所有提交的任务

你可以捕获 future

Future aFuture = executor.submit(aTaskThatRunsInParallelOrWhatYouCallASubTask);

不知何故,你需要知道你确实想取消任务,你需要调用

aFuture.cancel();

看起来你需要的东西比较复杂,我建议看看JMS,它非常成熟,或者AKKA可能更容易掌握。

关于java - 处理线程池中的优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40292906/

相关文章:

java - JMeter 以警告消息启动

python - 如何在Python中同时写入两个CSV?

c++ - QFuture 信号在错误的时间发出

java - 如何确保线程完成其任务,然后只有新线程可以在java中启动?

c# - 如何防止一个方法跨多个线程运行?

c++ - TBB parallel_for 线程池

具有共享只读内存的 C++ 线程池

java - 如果作业未完成,Spring 调度程序不会运行

JavaCv/OpenCv 错误 : what does it mean?

java - 使用速度模板和 JSON 生成 HTML?