Pergunta

gostaria de ter um SynchronousQueue onde inserir elementos de uma rosca com put(), de modo que a entrada é bloqueada até que o elemento é tomado em outro segmento.

No outro segmento Eu executar lotes de cálculos e de vez em quando quiser verificar se um elemento já está disponível, e consumi-lo. Mas parece que isEmpty() sempre retorna true, mesmo se outro segmento está esperando na chamada put().

Como na terra isso é possível? Aqui está o código de exemplo:

@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: Nem isEmpty () nem espiada () trabalho, um tem que usar poll (). Obrigado!

Foi útil?

Solução

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

isEmpty
public boolean isEmpty ()
Sempre retorna true. A SynchronousQueue não tem capacidade interna.

(não olhei para isso em grande detalhe, mas você pode querer dar uma olhada em ambos os poll ou tomar em vez)

Outras dicas

Além de resposta de Tim - você está fazendo nada no segmento de consumidor, mas continuamente chamando isEmpty () dentro de um loop. Ao invés de perguntar o OS para não executá-lo até que haja algo de útil para que ele faça, o segmento consumidor é constantemente ocupado. Mesmo se isEmpty funcionou corretamente, o segmento produtor raramente tem a chance de correr.

Você poderia (se isEmpty () fez um trabalho, ou você passou a usar poll ()) tornar o sono do consumidor para um pouco entre os testes quando a fila está vazia para dar ao produtor a chance de correr, ou (de preferência) apenas tirar o teste isEmpty () e deixar o bloco de rosca sobre a exclusão mútua dentro do take () de uma forma sensata em vez de voto.

seu código parece que você está tentando fazer uma pesquisa. porque não basta chamar o método poll ()?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top