如何在运行时获取石英线程池大小?

时间:2019-09-12 17:17:11

标签: java quartz

我有crystal-1.8.6 / java应用程序,它使用默认的org.quartz.simplSimpleThreadPool,并且"org.quartz.threadPool.threadCount"(池中的工作线程数)设置为20。

我想在运行时定期轮询池中当前可用的线程数以进行诊断,如果一段时间内它已经耗尽(当前池大小为0),请记录警告。

如何在运行时访问池中的当前可用线程数?

SimpleThreadPool提供了一种方法getPoolSize(),根据javadoc(“在ThreadPool中获取当前线程数。”),该方法可以提供我正在寻找的信息。但是如何获得对石英调度程序使用的SimpleThreadPool的引用?

我按如下方式初始化我的石英调度程序:

SchedulerFactory schedFact = new StdSchedulerFactory();
System.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME,
    this.defaultThreadName);
System.setProperty("org.quartz.threadPool.threadCount",
    ""+this.threadPoolSize);
scheduler = schedFact.getScheduler();

我正在考虑如下添加全局侦听器:

scheduler.addGlobalJobListener(new JobListener() {
    public void jobToBeExecuted(JobExecutionContext context) {
        Scheduler s = context.getScheduler();

        // How to get reference to thread pool from scheduler?
        // --> ...
    }
    // other JobListener interface methods 
    // ...
});

Scheduler中看不到任何直接访问threadPool实例或poolSize属性的方法。有办法吗?

答案: 经过几次试验,我找到了自己想分享的问题的答案:

  • 正如我在下面的评论中所述,getPoolSize()实际上对我不起作用,因为按照org.quartz.simplSimpleThreadPool中的实现,它只返回与threadCount相同的值(池),它将始终相同:
    public int getPoolSize() {
        return getThreadCount();
    }

    /**
     * <p>
     * Set the number of worker threads in the pool - has no effect after
     * <code>initialize()</code> has been called.
     * </p>
     */
    public void setThreadCount(int count) {
        this.count = count;
    }

  • 对我有用的方法是QuartzScheduler.getCurrentlyExecutingJobs()。返回列表的大小正是我所需要的。为了快速进行概念验证,我在调度程序中添加了以下全局侦听器,以记录当前使用的线程数(注意:我在示例代码中使用io.vavr.control.Try,有关更多信息,请参阅https://www.vavr.io/vavr-docs/#_try ):
scheduler.addGlobalJobListener(new JobListener() {
    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        Scheduler s = context.getScheduler();
        JobDetail jd = context.getJobDetail();
        // cast raw generic List to List<?> for stream() to work
        Try<List<?>> tryGetCurrentJobs = Try.of(() -> s.getCurrentlyExecutingJobs());
        tryGetCurrentJobs
        .onSuccess(jobs -> {
            List<JobExecutionContext> currentJobs = jobs.stream()
                .map(o -> (JobExecutionContext)o) // any type error will be discovered here
                .collect(Collectors.toList());
            logger.info(format(
                "job to be executed [%s:%s] - quartz scheduler is using %d out of %d threads in the pool.",
                jd.getGroup(), jd.getName(), currentJobs.size(), threadPoolSize));
            });
    }
    // other JobListener interface methods 
    // ...
});

  • 对于最终解决方案,我选择实现一个Singleton Watcher,它使用调度的线程池执行程序(在石英调度程序之外)运行一个线程。观察者将保留对石英调度程序的引用,并将在指定的时间间隔内收集池使用情况信息,对其进行分析并在池使用情况超出预定阈值时发送通知。

0 个答案:

没有答案