如何创建LIFO执行程序?

我想创建一个线程池,它将执行最近提交的任务。 有关如何完成此任务的任何建议?

谢谢


你可能只需实现你自己的BlockingQueue包装器,它将提供/轮询映射到堆栈。 然后将其用作传递给ThreadPoolExecutorBlockingQueue实现。 我的建议是打包一个现有的Deque实现,如ArrayDeque

  • 这不是同步的,所以你需要用同步程序包装每个BlockingQueue方法(如果不是更奇特的话)。
  • 您还需要为阻塞操作引入wait / notify条件。
  • 最后,您需要将一组BlockingQueue极性(“put”或“take”端)映射到出队列的另一端(将其视为堆栈)。
  • 请注意,有一些工作(参见Herlihy关于多处理器编程艺术的书籍)关于更快的并发堆栈,但我不认为JDK中有任何实现,我不确定Herlihy的实现是否提供阻塞风格。

    在Deque上执行

    我检查了Android文档,这表明Deque是为你准备的,所以这里是一个实现。 围绕堆栈执行包装也是一个相当简单的步骤,但Deque是首选。

    import java.util.Collection;
    import java.util.Iterator;
    import java.util.NoSuchElementException;
    import java.util.concurrent.BlockingDeque;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.concurrent.TimeUnit;
    
    
    public final class BlockingLifoQueue<T> implements BlockingQueue<T>
    {
      // we add and remove only from the end of the queue
      private final BlockingDeque<T> deque; 
    
      public BlockingLifoQueue()
      { deque = new LinkedBlockingDeque<T>(); }
    
      public boolean add(T e) {
        deque.addLast(e);
        return true;
      }
    
      public boolean contains(Object o)
      { return deque.contains(o); }
    
      public int drainTo(Collection<? super T> c)
      { return deque.drainTo(c); }
    
      public int drainTo(Collection<? super T> c, int maxElements)
      { return deque.drainTo(c,maxElements); }
    
      public boolean offer(T e)
      { return deque.offerLast(e); }
    
      public boolean offer(T e, long timeout, TimeUnit unit)
          throws InterruptedException
      { return deque.offerLast(e,timeout,unit); }
    
      public T poll(long timeout, TimeUnit unit) throws InterruptedException
      { return deque.pollLast(timeout, unit); }
    
      public void put(T e) throws InterruptedException
      { deque.putLast(e); }
    
      public int remainingCapacity()
      { return deque.size(); }
    
      public boolean remove(Object o)
      { return deque.remove(o); }
    
      public T take() throws InterruptedException
      { return deque.takeLast(); }
    
      public T element()
      {
        if (deque.isEmpty()) { 
          throw new NoSuchElementException("empty stack");
        }
    
        return deque.pollLast();
      }
    
      public T peek()
      { return deque.peekLast(); }
    
      public T poll()
      { return deque.pollLast(); } // deque.peekLast(); } -- fixed typo.
    
      public T remove()
      {
        if (deque.isEmpty()) { 
          throw new NoSuchElementException("empty stack");
        }
    
        return deque.pollLast();
      }
    
      public boolean addAll(Collection<? extends T> c)
      { 
        for (T e : c) { deque.add(e); }
        return true;
      }
    
      public void clear()
      { deque.clear();}
    
      public boolean containsAll(Collection<?> c)
      { return deque.containsAll(c); }
    
      public boolean isEmpty()
      {  return deque.isEmpty(); }
    
      public Iterator<T> iterator()
      { return deque.descendingIterator(); }
    
      public boolean removeAll(Collection<?> c)
      { return deque.removeAll(c); }
    
      public boolean retainAll(Collection<?> c)
      { return deque.retainAll(c); }
    
      public int size()
      { return deque.size(); }
    
      public Object[] toArray()
      { return deque.toArray(); }
    
      public <T> T[] toArray(T[] a)
      { return deque.toArray(a); }
    }
    

    与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 extends BlockingQueue)

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

    你可以使用push和pop来代替offerFirst和removeFirst。 当然,你将不得不实施BlockingQueue并完成该实现。


    这很容易通过使用PriorityQueuePriorityBlockingQueue ,其中最近排队的项目获得最高优先级。

    链接地址: http://www.djcxy.com/p/93109.html

    上一篇: How to create LIFO executor?

    下一篇: Consequences of drawable.setCallback(null);