ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor

首先:我已经阅读了以下两个问题及其可能的解决方案:

  • ScheduledThreadPoolExecutors and custom queue
  • Java Executors: how can I set task priority?

  • 我遇到的难题是我想使用自定义的BlockingQueue或更确切地说是一个不同但特定的队列,即PriorityBlockingQueue和自定义的Comparator,后者按优先级对队列进行排序。
    ThreadPoolExecutor确实在其构造函数中支持自定义队列,但它不通过ScheduledExecutorService接口(interface)实现方法。因此,我去找到了子类ScheduledThreadPoolExecutor,但是它不支持自定义队列,而是使用了DelayedWorkQueue

    问题:
  • 我无法从ScheduledThreadPoolExecutor扩展,因为为我自己的类创建构造函数不会做任何事情,因为ScheduledThreadPoolExecutor的构造函数不接受自定义队列作为参数。
  • 我无法复制ThreadPoolExecutor类的内容和ScheduledThreadPoolExecutor的实现,因为它使用了很多没有修饰符声明的方法(例如canRunInCurrentState(boolean periodic)和此调用调用的所有方法),这不允许我访问该方法因为即使它是ThreadPoolExecutor的子类,它也不在同一个包中。

  • 我当前的实现如下所示:
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.Callable;
    import java.util.concurrent.PriorityBlockingQueue;
    import java.util.concurrent.RejectedExecutionHandler;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledFuture;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    import com.croemheld.tasks.PriorityTaskComparator;
    
    public class ScheduledPriorityThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService {
    
        private static final int INITIAL_QUEUE_SIZE = 10;
    
        public ScheduledPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                TimeUnit unit, BlockingQueue<Runnable> workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                new PriorityBlockingQueue<Runnable>(INITIAL_QUEUE_SIZE, new PriorityTaskComparator()));
        }
    
        public ScheduledPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                new PriorityBlockingQueue<Runnable>(INITIAL_QUEUE_SIZE, new PriorityTaskComparator()), handler);
        }
    
        public ScheduledPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                new PriorityBlockingQueue<Runnable>(INITIAL_QUEUE_SIZE, new PriorityTaskComparator()), threadFactory);
        }
    
        public ScheduledPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
                RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                new PriorityBlockingQueue<Runnable>(INITIAL_QUEUE_SIZE, new PriorityTaskComparator()), threadFactory, handler);
        }
    
        @Override
        public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    

    如您所见,构造函数问题得到了解决,但是仍然保留了ScheduledExecutorService中调度方法的实现。

    所以我问你,有没有办法将Comparator传递到队列,或者是一种简单但不太详尽的方法来创建自己的执行程序类,该类执行ScheduledExecutorService中的方法并提供ThreadPoolExecutor类中的方法以及使用PriorityBlockingQueue吗?

    最佳答案

    如果我理解您的问题,则希望根据自定义优先级定期执行一些任务。除了发明自己的ExecutorService之外,我建议您退后一步,看看您的设计。您可能希望将调度与优先级划分和任务执行分开:

  • 由于ThreadPoolExecutor接受自定义BlockingQueue,因此您可以轻松实现自己的优先级。然后,只需定期从代码中的其他位置提交任务即可。
  • 如果您坚持使用ScheduledThreadPoolExecutor,则可以进行调度,但是必须自己实现优先级。您可能会因此而变得非常有创意,但是一个选择可能是拥有一个编排任务,该任务从自定义的BlockingQueue拾取任务并将其提交到池中。
  • 关于java - 在ScheduledThreadPoolExecutor中将PriorityBlockingQueue与Comparator一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48245458/

    10-09 04:01