Java阻止列表实现

时间:2015-04-27 07:26:29

标签: java list blocking

我在SO和Google上搜索了这个问题的答案,但到目前为止找不到合适的解决方案。

我目前正在处理图形路由问题中的LayerManager。经理负责提供和重置固定的图层集。

我想使用阻止列表实现Consumer-Producer模式,以便在没有可用的自由层的情况下阻止传入路由请求。到目前为止我只发现了一个blocking queue,但由于我们不需要FIFO,LIFO但随机访问队列并不真正起作用。为了更精确一点,这样的事情应该是可能的:

/* this should be blocking until a layer becomes available */
public Layer getLayer(){ 

    for ( Layer layer : layers ) {
        if ( layer.isUnused() && layer.matches(request) )
            return layers.pop(layer);
    }
}

有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:0)

您正在寻找的是“信号量”。

  1. 创建信号量类
  2. 将其作为字段添加到图层类
  3. 实施例

     public class Semaphore 
    {
        private boolean signal = false;
    
        public synchronized boolean take() 
        {
           if(this.signal==true)
                return false;  //already in use
           this.signal = true;
           this.notify();
           return true;
        }
    
         public synchronized void release() throws InterruptedException
         {
            while(!this.signal) wait();
            this.signal = false;
         }
    
    
         public boolean isUnused()
         {
             return !signal ;
         }
    
    }
    
    
    //2.
    class Layer
    {
        Semaphore sem =null;
    
        /*your code*/
         /*sem = new Semaphore(); in constructors*/
        public boolean take()
        {
            return this.sem.take();
        }
    
        public void release()
        {
            this.sem.release();
        }
    
        public Layer getLayer()
        { 
    
            for ( Layer layer : layers ) 
            {
             if ( layer.matches(request) && layer.take())
                 return layer;
            }
    
             return null;
        }
    }
    


    同步方法处理访问并发

    3.遍历getLayer直到

    Layer l=null;
    while(l==null)
    {
        l= getlayer();
        Thread.sleep(100); //set time
    }
     // continue
     // do not forget to release the layer when you are done
    

答案 1 :(得分:0)

尝试使用"@icon-font-path: '../../plugins/system/t3/base-bs3/bootstrap/fonts/'"; 。我们的想法是在Map<String, BlockingQueue<Layer>>内保留免费图层。每个请求都有自己的队列。

BlockingQueue

答案 2 :(得分:0)

我不太确定我是否正确了解您的需求,但您可以使用阻塞队列并将结果放入列表中。如果在列表中找不到合适的层,则调用wait()并在从队列中将新项添加到列表时再次检查。这听起来似乎可以在概念上起作用,即使下面的代码没有做到正确(我很确定这不是很正确的同步)

public class PredicateBlockingQueue<Product> {

private final List<Product> products = new LinkedList<Product>();
private final BlockingQueue<Product> queue;
private final Thread consumer;

public PredicateBlockingQueue(int capacity) {
    queue = new ArrayBlockingQueue<Product>(capacity);

    consumer = new Thread() {
        @Override
        public void run() {
            while(!Thread.interrupted()) {
                try {
                    products.add(queue.take());
                    synchronized(queue) {
                        queue.notifyAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    consumer.start();
}

public void put(Product product) throws InterruptedException {
    queue.put(product);
}

public Product take(Predicate<Product> predicate) throws InterruptedException {
    Product product;
    while((product=find(predicate))==null) {
        synchronized(queue) {
            queue.wait();
        }
    }
    return product;
}

private synchronized Product find(Predicate<Product> predicate) {
    Iterator<Product> it = products.iterator();
    while(it.hasNext()) {
        Product product = it.next();
        if(predicate.test(product)) {
            it.remove();
            return product;
        }
    }
    return null;
}