2008-08-23 8 views
4

Was ist die beste Methode, um Objekte aus einer BlockingQueue in einem gleichzeitigen Programm zu erhalten, ohne eine Race Condition zu treffen? Ich mache zur Zeit die folgenden und ich bin nicht überzeugt, dass es die beste Methode ist:Beste Methode, um Objekte aus einer BlockingQueue in einem gleichzeitigen Programm zu erhalten?

BlockingQueue<Violation> vQueue; 
/* 
in the constructor I pass in a BlockingQueue object 
full of violations that need to be processed - cut out for brevity 
*/ 

Violation v; 
while ((v = vQueue.poll(500, TimeUnit.MILLISECONDS)) != null) { 
    // do stuff with the violation 
} 

ich noch eine Race-Bedingung zu treffen ... aber, ich bin nicht allzu sicher, ob dies wirklich sicher ist .

Antwort

6
class Producer implements Runnable { 
    private final BlockingQueue queue; 
    Producer(BlockingQueue q) { queue = q; } 
    public void run() { 
    try { 
     while (true) { queue.put(produce()); } 
    } catch (InterruptedException ex) { ... handle ...} 
    } 
    Object produce() { ... } 
} 

class Consumer implements Runnable { 
    private final BlockingQueue queue; 
    Consumer(BlockingQueue q) { queue = q; } 
    public void run() { 
    try { 
     while (true) { consume(queue.take()); } 
    } catch (InterruptedException ex) { ... handle ...} 
    } 
    void consume(Object x) { ... } 
} 

class Setup { 
    void main() { 
    BlockingQueue q = new SomeQueueImplementation(); 
    Producer p = new Producer(q); 
    Consumer c1 = new Consumer(q); 
    Consumer c2 = new Consumer(q); 
    new Thread(p).start(); 
    new Thread(c1).start(); 
    new Thread(c2).start(); 
    } 
} 

Dieses Beispiel stammt aus der JDK 1.6 docs of BlockingQueue. So können Sie sehen, dass Sie es richtig machen. Hier ist das Zitat, das Ihnen sagt, dass sie arbeiten haben:

Speicherkonsistenz Effekte: Wie bei anderen gleichzeitigen Sammlungen, Aktionen in einem Thread vor dem Platzieren eines Objekts in eine Blocking geschehen zuvor Aktionen im Anschluss an der Zugriff oder Entfernung dieses Elements aus der BlockingQueue in einem anderen Thread.