与后进先出顺序执行者服务 [英] Executor Service with LIFO ordering

查看:170
本文介绍了与后进先出顺序执行者服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个懒imageDownloader为使用的ExecutorService我的应用程序。 (这让我有多少下载量在什么时间等运行paralel伟大的控制)

i wrote a lazy imageDownloader for my app using an ExecutorService. (It gives me great control about how many downloads are running paralel at what time and so on)

现在,我有唯一的问题是,如果我提出一个任务,它结束了在quene(FIFO)的尾部。

Now the only problem that i have, is that if i submit a task it ends up at the tail of the quene (FIFO).

有谁知道如何改变呢?

谢谢!

推荐答案

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

You will need to specify the queue type that the ExecutorService is using.

通常情况下,你可能会通过检索中的静态方法执行人的ExecutorService的。相反,你将需要直接实例之一,通过在队列中键入要提供后进先出法。

Typically you might be retrieving an ExecutorService via the static methods in Executors. Instead you will need to instantiate one directly and pass in the Queue type that you want that provides LIFO.

例如,为了创建一个LIFO线程池执行者,您可以使用下面的构造函数。

EG, to create a LIFO thread pool executor, you could use the following constructor.

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

和传递一个后进先出队列中的最后一个参数。

and pass in a LIFO queue as the final parameter.

有一个在Java集合,我知道没有LIFO队列(请纠正我如果错了),但你可以轻松地将创建可扩展的LinkedBlockingQueue一个匿名内部类,并覆盖相应的方法。

There is no LIFO queue in the java collections that I am aware of (please correct me if wrong), but you could easily just create an anonymous inner class that extends LinkedBlockingQueue and overrides the appropriate methods.

例如,(未经测试)

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);
  }

});

更新回应意见。

UPDATE in response to comments.

我们可以使用一个阻塞队列,它包装一个优先级队列。我们必须包装,因为执行官预计可运行,但我们需要时间戳了。

We can use a blocking queue that wraps a priority queue. We have to wrap because the Executor expects runnables but we need timestamps too.

// 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
    });

这篇关于与后进先出顺序执行者服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆