我使用ExecutorService为我的应用编写了一个懒惰的图像下载器。它使我可以很好地控制在什么时候等时间并行运行多少个下载。

现在,我唯一的问题是,如果我提交任务,它最终将排在队列的尾部(FIFO)。

有人知道如何将其更改为LIFO吗?

最佳答案

您将需要指定ExecutorService使用的队列类型。

通常,您可能通过Executors中的静态方法检索ExecutorService。相反,您将需要直接实例化一个实例,然后传递您想要提供LIFO的Queue类型。

EG,要创建LIFO线程池执行程序,可以使用以下构造函数。

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)

并传入LIFO队列作为最终参数。

我知道的Java集合中没有LIFO队列(如果出错,请更正),但是您可以轻松地创建一个扩展LinkedBlockingQueue并覆盖适当方法的匿名内部类。

例如,(未测试)
ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 16, 1, TimeUnit.MINUTES, new LinkedBlockingQueue() {

  @Override
  public void put(Object obj) {
    // override to put objects at the front of the list
    super.addFirst(obj);
  }

});

更新以回应评论。

我们可以使用包装优先级队列的阻塞队列。我们必须包装一下,因为执行程序需要可运行对象,但我们也需要时间戳记。
// the class that will wrap the runnables
static class Pair {

     long   timestamp;
    Runnable    runnable;

    Pair(Runnable r) {
        this.timestamp = System.currentTimeMillis();
        this.runnable = r;
    }
}


    ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 16, 1, TimeUnit.MINUTES, new BlockingQueue<Runnable>() {

        private Comparator          comparator      = new Comparator<Pair>() {

                                                @Override
                                                public int compare(Pair arg0, Pair arg1) {
                                                    Long t1 = arg0.timestamp;
                                                    Long t2 = arg1.timestamp;
                                                    // compare in reverse to get oldest first. Could also do
                                                    // -t1.compareTo(t2);
                                                    return t2.compareTo(t1);
                                                }
                                            };

        private PriorityBlockingQueue<Pair> backingQueue    = new PriorityBlockingQueue<Pair>(11, comparator);

        @Override
        public boolean add(Runnable r) {
            return backingQueue.add(new Pair(r));
        }

        @Override
        public boolean offer(Runnable r) {
            return backingQueue.offer(new Pair(r));
        }

        @Override
        public boolean offer(Runnable r, long timeout, TimeUnit unit) {
            return backingQueue.offer(new Pair(r), timeout, unit);
        }

        // implement / delegate rest of methods to the backing queue
    });

关于android - 使用LIFO订购的执行器服务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6107609/

10-13 03:35