如何创建LIFO执行器?

时间:2011-01-06 21:28:06

标签: java multithreading threadpool

我想创建一个线程池,它将执行最近提交的任务。有关如何实现这一目标的任何建议吗?

谢谢

5 个答案:

答案 0 :(得分:21)

您可能只需要实现自己的BlockingQueue包装器,将offer / poll映射到堆栈。然后将其用作传递给BlockingQueue的{​​{1}}实现。我的建议是包装一个现有的ThreadPoolExecutor实现,例如ArrayDeque

  • 这不是同步的,所以你需要用同步器包装每个Deque方法(如果不是更奇特的东西)。
  • 您还需要为阻止操作引入BlockingQueue / wait条件。
  • 最后,你需要将一组notify极性(“put”或“take”侧)映射到出队的同一端(将其视为一个堆)。

请注意,在更快的并发堆栈上有一些工作(参见Herlihy关于多处理器编程的艺术的书),但我不认为JDK中有任何实现,我不是确定Herlihy的实现是否会提供阻塞味道。

Deque上面的实现

我为你检查了Android documentation, which suggests that Deque is around,所以这是一个实现。这也是在堆栈周围做包装的一个相当简单的步骤,但Deque是首选。

BlockingQueue

答案 1 :(得分:8)

类似于andersoj所建议的,但是可以使用BlockingDeque。

您可以将LinkedBlockingDeque类扩展为在提供和删除时始终弹出并按下。

public class FIFOBlockingDeque<T> extends LinkedBlockingDeque<T> {

 @Override
 public boolean offer(T t) {
  return super.offerFirst(t);
 }

 @Override
 public T remove() {
  return super.removeFirst();
 }
}

然后将其作为参数传递给ThreadPoolExecutor(BlockingDeque扩展BlockingQueue)

编辑: 要回答您的评论问题,您可以使用提供的java.util.Stack而不是继承Deque。它被认为是遗留的,如果你只局限于Java库本身,这将是最好的。

您可以使用push和pop来代替offerFirst和removeFirst。当然,您必须实现BlockingQueue并完成该实现。

答案 2 :(得分:1)

使用PriorityQueuePriorityBlockingQueue可以轻松完成此操作,其中最近排队的项目具有最高优先级。

答案 3 :(得分:0)

ThreadPoolExecutor构造函数接受用于保持任务执行的BlockingQueue。您可能需要实现BlockingQueue的自定义版本以支持LIFO策略。

答案 4 :(得分:0)

我认为在使用BlockingLifoQueue的方法中,LIFO的@andersoj实现中存在错误。

remove方法应该是这样的:

  public T remove()
  {
    if (deque.isEmpty()) { 
      throw new NoSuchElementException("empty stack");
    }

    return deque.pollFirst(); // instead of pollLast()
  }

对不起,如果我错了,但对我来说没有意义......在LIFO中查看最后一个。