2009-01-22 10 views
0

Je voudrais avoir un SynchronousQueue où j'insère des éléments d'un fil avec put(), ainsi l'entrée est bloquée jusqu'à ce que l'élément soit pris dans un autre fil.BlockingQueue: put() et isEmpty() ne fonctionnent pas ensemble?

Dans l'autre thread j'effectue beaucoup de calculs et de temps en temps je veux vérifier si un élément est déjà disponible, et le consommer. Mais il semble que isEmpty() retourne toujours vrai, même si un autre thread attend à l'appel put().

Comment diable est-ce possible? Voici l'exemple de code:

@Test 
public void testQueue() throws InterruptedException { 
    final BlockingQueue<Integer> queue = new SynchronousQueue<Integer>(); 

    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (true) { 
       if (!queue.isEmpty()) { 
        try { 
         queue.take(); 
         System.out.println("taken!"); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
       // do useful computations here (busy wait) 
      } 
     } 
    }); 
    t.start(); 

    queue.put(1234); 
    // this point is never reached! 
    System.out.println("hello"); 
} 

EDIT: Ni isEmpty(), ni coup d'oeil() travail, on doit utiliser poll(). Merci!

Répondre

1

En plus de la réponse de Tim - vous ne faites rien dans la thread de consommation, mais appel continu isEmpty() dans une boucle serrée. Plutôt que de demander au système d'exploitation de ne pas l'exécuter tant qu'il n'y a pas quelque chose d'utile à faire, le thread consommateur est continuellement occupé. Même si isEmpty fonctionne correctement, le thread de production aura rarement une chance de s'exécuter. Vous pourriez (si isEmpty() a fonctionné, ou vous êtes passé à l'aide de poll()) faire en sorte que le consommateur dorme un peu entre les tests quand la file est vide pour donner au producteur une chance de fonctionner, ou (de préférence) Il suffit de sortir le test isEmpty() et de laisser le thread thread sur le mutex dans le take() d'une manière sensée au lieu d'interroger.

1

votre code ressemble à une tentative de sondage. pourquoi ne pas simplement appeler la méthode poll()?

Questions connexes