2012-10-08 2 views
5

Java supporta qualsiasi oggetto o meccanismo di coda per gestire il trattamento batch?abbiamo un oggetto o un meccanismo di coda java per gestire il trattamento batch?

ex: abbiamo una coda (o qualsiasi oggetto di coda desiderato), qualche produttore spinge l'articolo nella coda uno per uno, il mio obiettivo è quando abbiamo 10 elementi o più di 10 elementi in questa coda, possiamo attivare alcuni gestore per trattarlo in un unico lotto.

o non viene attivato automaticamente, è necessario trovare un modo per eseguire il ciclo della coda con garbo sul lato del gestore.

abbiamo un oggetto o una libreria ad alte prestazioni tipico per gestirlo?

grazie, Emre

risposta

0

Date un'occhiata alla documentazione delle API di interfaccia java.util.Queue, che ha diverse implementazioni.

C'è anche un'API standard, Java Message Service (JMS) per gestire i sistemi di accodamento per lo scambio di messaggi tra diversi processi.

+1

Come questo risolve il problema del dosaggio? Non penso che lo faccia. –

0

Penso che CountDownLatch sia quello che ti serve, o possibilmente lo CyclicBarrier. Ciò consentirebbe di impostare un punto di sincronizzazione che attiverà i consumatori dopo che si è verificato un certo numero di operazioni e sarà possibile utilizzare una coda standard come oggetto contenitore.

+0

puoi fornire qualche frammento di codice, sarebbe bello capire il pensiero. –

+1

Un 'CountDownLatch' è particolarmente utile quando si producono più thread o più thread (o entrambi). Non è chiaro che sia il caso qui. –

2

L'elaborazione batch in coda potrebbe essere ottenibile con wait/notify, qualcosa come se si potesse bloccare la chiamata al thread contro la risorsa fino a quando è disponibile o meno.

public class MyQueue implements Queue<Object>{ 
     public synchronized List<Object> peek() { 
     if(this.list.size()>=10) 
        this.list.wait(); 
     return Collections.subList(0,10); 
    } 
     @Override 
    public boolean add(Object e) { 
     this.list.add(e); 
       if(this.list.size()>=10) 
        this.list.notifyAll(); 
     return false; 
    } 
} 

non viene attivato automaticamente

In questo caso si può chiamare attendere con il tempo specificato out.

2

È possibile utilizzare BlockingQueue.drainTo() per ottenere automaticamente batch di attività da eseguire. Questo è adatto a oltre 100K task al secondo.

Se avete bisogno di prestazioni più elevate in coda è possibile utilizzare il più complesso Disruptor o Java Chronicle che può coda in milioni di operazioni al secondo, sia di supporto auto-dosaggio.

+0

quindi, vuoi dire, dobbiamo implementarlo sul lato del metodo, giusto? aggiungiamo un ciclo per eseguire BlockingQueue.drainTo() per ottenere l'elenco con gli elementi della coda, quindi richiamare il processore per gestirlo. –

+0

Potresti farlo. Sia i produttori che i consumatori hanno metodi;) –

1

Ecco un rapido tentativo di elaborazione degli oggetti in batch, utilizzando un thread in background per raccogliere e oggetti di processo spinto su una coda da altri thread:

public abstract class Batcher<E> implements Runnable { 

    public static interface BatchProcessor<E> { 
     public void processBatch(List<E> batch); 
    } 

    private final BlockingQueue<E> queue; 
    private final BatchProcessor<E> processor; 

    private Batcher(BlockingQueue<E> queue, BatchProcessor<E> processor) { 
     this.queue = queue; 
     this.processor = processor; 
    } 

    @Override 
    public void run() { 
     try { 
      while (true) { 
       List<E> batch = new ArrayList<E>(); 
       for (int i = 0; i < 10; i++) { 
        batch.add(queue.take()); 
       } 
       processor.processBatch(batch); 
      } 
     } catch (InterruptedException e) { 
      return; 
     } 
    } 

} 

Per utilizzare questo, si crea una BlockingQueue e appoggiare oggetti sulla creare un'istanza di un'implementazione di BatchProcessor per elaborare i batch, quindi creare un'istanza di Batcher per pompare gli oggetti dal primo al secondo.