2015-04-27 15 views
6

Tôi đã tìm kiếm câu trả lời cho câu hỏi này trên SO và Google nhưng không thể tìm thấy giải pháp thích hợp cho đến thời điểm này.Thực thi danh sách chặn Java

Tôi hiện đang làm việc trên Trình quản lý lớp trong vấn đề định tuyến biểu đồ. Người quản lý chịu trách nhiệm cung cấp và đặt lại một nhóm lớp cố định.

Tôi muốn triển khai mẫu Người tiêu dùng-Nhà sản xuất với danh sách chặn, để yêu cầu định tuyến đến bị chặn miễn là không có lớp miễn phí. Cho đến nay tôi chỉ tìm thấy một blocking queue nhưng kể từ khi chúng tôi không cần FIFO, LIFO nhưng truy cập ngẫu nhiên một hàng đợi không thực sự làm việc. Để chính xác hơn một chút, có thể có điều gì đó như thế này:

Có cách nào để đạt được điều này không?

+0

gì về java.util.concurrent.PriorityBlockingQueue với sánh của riêng bạn ? – StanislavL

+0

Cảm ơn. Vâng, lớp không thực sự so sánh theo ý kiến ​​của tôi. chúng chỉ khớp với một yêu cầu nhất định. –

Trả lời

0

Điều bạn đang tìm kiếm được gọi là "Semaphore".

  1. Tạo một lớp Semaphore
  2. Thêm nó như là một lĩnh vực vào Layer lớp

Ví dụ

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


phương pháp đồng bộ xử lý truy cập sự đồng

3. Vòng qua getLayer cho đến khi

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

đó là loại những gì tôi làm bây giờ, tôi không thích mô hình này thông báo/chờ đợi. nó dễ bị lỗi hơn nhiều so với việc chặn –

0

Cố gắng sử dụng Map<String, BlockingQueue<Layer>>. Ý tưởng là giữ các Lớp miễn phí bên trong BlockingQueue. Mọi yêu cầu đều có hàng đợi của riêng anh ấy.

public class LayerQueue { 

    Map<String, BlockingQueue<Layer>> freeLayers = Collections.synchronizedMap(new HashMap<String, BlockingQueue<Layer>>()); 

    public LayerQueue() { 
     //init QUEUEs 
     freeLayers.put("request-1", new ArrayBlockingQueue<Layer>(1)); // one to one... 
     freeLayers.put("request-2", new ArrayBlockingQueue<Layer>(1)); 
     [...] 
    } 

    public void addUnusedLayer(Layer layer, String request) { 
     BlockingQueue<Layer> freeLayersForRequest = freeLayers.get(request); 
     freeLayersForRequest.add(layer); 
    } 

    public Layer getLayer(String request) { 

     BlockingQueue<Layer> freeLayersForRequest = freeLayers.get(request); 

     try { 
      return freeLayersForRequest.take(); // blocks until a layer becomes available 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 
+0

1 có một lớp cho mỗi yêu cầu, cũng bản đồ không phải là kích thước cố định –

+0

@DanielGerber tại sao chính xác nó phải là một vấn đề? – dit

+0

Vì 1 lớp có thể cần tới 500MB RAM. –

0

Tôi không chắc chắn tôi hiểu nhu cầu của bạn một cách chính xác, nhưng bạn có thể tiêu thụ hàng đợi chặn và đưa kết quả vào danh sách. Nếu không tìm thấy một lớp thích hợp trong danh sách, hãy gọi wait() và kiểm tra lại khi một mục mới được thêm vào danh sách từ hàng đợi. Điều này nghe như nó có thể làm việc về mặt khái niệm, thậm chí nếu mã dưới đây không làm cho nó đúng (tôi khá chắc chắn đây không phải là khá đúng đồng bộ)

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; 
} 
Các vấn đề liên quan