有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将线程优先级传递给线程池

我有一个Java组件,它执行一些超复杂的业务逻辑,其中一些是并行的,执行子任务的线程是池化的。现在,对这个组件的每个请求都可以有一些优先级,这些优先级以某种方式映射到线程优先级。在执行开始时,我可以为执行线程分配适当的优先级。问题在于将优先级传递给执行子任务的每个线程。我知道产生一个新的子线程将实现这一点,因为子线程继承父线程的优先级,但我想利用线程池。问题的答案是:

  • 有没有办法确保执行路径中的每个线程都有适当的优先级
  • 我如何在执行的每个阶段监控线程优先级,当然我不想硬编码任何跟踪代码?我想到的一件事是在BTrace中写一些跟踪脚本

干杯。 托梅克


共 (5) 个答案

  1. # 1 楼答案

    您希望使用线程池,如果您必须生成新线程来设置作业优先级,那么线程池将变得无用

    我认为您希望每个作业(而不是线程)具有不同的优先级。如果是这种情况,让我们看看ThreadPoolExecutor的构造函数签名:

    ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
    TimeUnit unit, BlockingQueue<Runnable> workQueue)
    
    • 不要使用推荐的Executors工厂方法来构建线程池,而是使用它的众多签名中的一个,自己动手new ThreadPoolExecutor(...)
    • Executors.defaultThreadFactory传递到这个构造函数中(上面列出的签名在内部执行此操作)。这将在创建线程时自动执行线程优先级分配(对于固定大小的线程池,在应用程序启动时,每个线程只应执行一次)
    • BlockingQueue<Runnable>PriorityBlockingQueue<Runnable>传递到此构造函数。这是一个队列,允许您对作业进行优先级排序(而不是线程
    • Runnable扩展为一个抽象的PriorityRunnable类,该类允许获取/设置优先级。它们代表了作业,因此当你想做一个新作业时,只需扩展它,并根据该作业的情况自定义设置优先级
    • 实现Comparator在将元素插入队列时对元素执行排序,并让该队列使用它
    • 将作业添加到队列中

    请注意,如果此时已经填充了队列(例如,对于批处理应用程序),则可以在构建后立即调用executor.prestartAllCoreThreads()executor.prestartCoreThread(n)

    这一切都非常简单,而且只需要几行代码就可以完成

    编辑:刚刚发现同样的方法正在讨论over at Java Ranch

  2. # 2 楼答案

    我最近实现了这个。我按照尼克·威吉尔的建议做了

    但你不能照他的建议去做,因为ThreadPoolExecutor不会将你要求的作业放入工作队列——相反,它会将它们包装在自己的RunnableFuture中,并将它们放入队列中。所以你必须重写它的newTaskFor方法来传递优先级

    源代码在Apache 2.0许可下在线: https://github.com/TheClimateCorporation/claypoole/blob/master/src/java/com/climate/claypoole/impl/PriorityThreadpoolImpl.java

  3. # 3 楼答案

    就设置线程的优先级而言,可以使用Executors类的不同方法,这些方法采用ThreadFactory。该工厂将负责根据传入的“Runnable”创建线程

    关于监控,当你说“执行的每个阶段”时,你能推断出你试图解决的场景吗?正如其他地方一样,由于Java和OS线程优先级之间没有明确的映射关系,依赖这些优先级将是一件坏事,如果您在这里尝试的是这样的话

  4. # 4 楼答案

    这可以解决你的问题:线程。currentThread()。设置优先级([1..5])

    你可以在任何地方使用它们。如果从线程池启动的runnable中使用它们,则可以控制单线程优先级,并根据需要进行更改

  5. # 5 楼答案

    我想你已经知道了这一点,但JDK线程的优先级值是否重要是高度特定于操作系统的,可能会转化为“没有任何影响”。你确定这真的很重要吗?如果是这样的话,也许可以编辑问题,提及系统运行的操作系统

    另外:甚至尝试使用线程优先级也不是很常见;除了不一定有效的优先事项之外,即使它们有效,也要充分利用它们。更常见的是使用同步原语,以及控制并发级别(活动线程的数量),而不是优先级。这是因为拥有比系统内核更多的活动CPU边界线程很少有好处