Question

J'aimerais avoir un SynchronousQueue dans lequel j'insère des éléments d'un thread avec put () , afin que l'entrée soit bloquée jusqu'à ce que l'élément soit repris dans un autre thread.

Dans l'autre fil, j'effectue de nombreux calculs et je veux de temps en temps vérifier si un élément est déjà disponible et le consommer. Mais il semble que isEmpty () renvoie toujours la valeur true, même si un autre thread est en attente à l'appel put () .

Comment 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 peek () ne fonctionnent, il faut utiliser poll (). Merci!

Était-ce utile?

La solution

De http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/SynchronousQueue.html#put(E) :

isEmpty
public boolean isEmpty ()
Retourne toujours vrai. Une file d'attente synchrone n'a pas de capacité interne.

(nous n'avons pas examiné cette question en détail, mais vous souhaiterez peut-être jeter un coup d'œil à sondage ou à prendre à la place)

.

Autres conseils

En plus de la réponse de Tim, vous ne faites rien dans le fil consommateur mais vous appelez continuellement isEmpty () dans une boucle serrée. Plutôt que de demander au système d'exploitation de ne pas l'exécuter avant d'avoir trouvé quelque chose d'utile à faire, le thread consommateur est occupé en permanence. Même si isEmpty fonctionnait correctement, le thread producteur aurait rarement l'occasion de s'exécuter.

Vous pourriez (si isEmpty () fonctionnait ou si vous utilisiez poll ()) pour que le consommateur dorme un peu entre les tests lorsque la file est vide pour donner au producteur une chance de s'exécuter, ou (de préférence) juste sortez le test isEmpty () et laissez le thread se bloquer sur le mutex à l’intérieur de take () de manière judicieuse au lieu de scruter.

votre code ressemble à celui que vous essayez de faire un sondage. pourquoi ne pas simplement appeler la méthode poll ()?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top