2008-10-18 5 views
1

Essentiellement ce que je veux est un BlockingQueue de taille = 1. J'ai un thread "écouteur" qui attend simplement, bloquant jusqu'à ce qu'un objet soit mis dans la file d'attente, puis le récupère - et un thread "producteur" qui met réellement l'objet dans la file d'attente.Java BlockingQueue de taille = 1?

Je peux implémenter ceci avec quelques blocs synchronisés et une implémentation de BlockingQueue, mais cela semble être trop compliqué. Existe-t-il une meilleure façon de faire ce que je veux?

interface Exemple:

public interface Wait<T> { 
    /** 
    * If "put" has never been called on this object, then this method will 
    * block and wait until it has. Once "put" has been called with some T, this 
    * method will return that T immediately. 
    */ 
    public T get() throws InterruptedException; 

    /** 
    * @param object The object to return to callers of get(). If called more 
    * than once, will throw an {@link IllegalStateException}. 
    */ 
    public void put(T object); 
} 
+1

Eh bien, c'est exactement ce que le borné nouveau ArrayBlockingQueue (1) est pour (utiliser la méthode « ajouter », pas mettre'). L'objet est assez léger en termes de synchronisation et les frais généraux de mémoire ne devraient pas faire de mal à moins que vous en ayez des dizaines de milliers. Avez-vous des préoccupations particulières? – ddimitrov

Répondre

0

Je trouve le code pour une classe appelée « ObjectLatch » ici: http://forums.sun.com/thread.jspa?threadID=5321141

package jfco.progs; 

import java.util.concurrent.CountDownLatch; 

/** 
* <H1>A Blocking Object Latch</H1> This class implements a blocking object 
* latch, that acts as a synchronizer between a producer of an object and it's 
* consumer(s). 
* <p> 
* An object is set with <code>set()</code>only ONCE. Further attempts to set 
* the object are just ignored.<br> 
* <p> 
* Consumers request the object with <code>get()</code>. If the object is not 
* already set, consumers are blocked waiting until the object is available or <br> 
* until an interrupt (InteruptedException) terminates the wait. 
* <p> 
* The latch can be tested for object availability with isAvailable(), which 
* answers true if the object has already been set. <br> 
*/ 
public class ObjectLatch<R> { 

    /** The object. */ 
    private R object = null; 

    /** The latch counter created and set to 1. */ 
    private final CountDownLatch latch = new CountDownLatch(1); 

    /** 
    * Checks if the object is already available (has been already set). 
    * 
    * @return true, if the object is already available (has been already set) 
    */ 
    public boolean isAvailable() { 
     return latch.getCount() == 0; 
    } 

    /** 
    * Sets the object if it is not already set. Otherwise ignore this request. 
    * 
    * @param object 
    *   the object 
    */ 
    public synchronized void set(R object) { 
     if (!isAvailable()) { 
      this.object = object; 
      latch.countDown(); 
     } 
    } 

    /** 
    * Get the object if it is already available (has already been set). 
    * <p> 
    * If it is not available, wait until it is or until an interrupt 
    * (InterruptedException) terminates the wait. 
    * 
    * @return the object if it is already available (has already been set) 
    * 
    * @throws InterruptedException 
    */ 
    public R get() throws InterruptedException { 
     latch.await(); 
     synchronized (this) { 
      return object; 
     } 
    } 
} 
2

Vous voulez dire quelque chose comme SynchronousQueue? Une autre classe utile est Exchanger

+0

Non, pas tout à fait. J'ai ajouté un exemple plus précis de ce que je recherche. – Ross

Questions connexes