Pergunta

Eu estou tentando ter o meu principal geram thread off uma nova linha e, depois de algum tempo, levantar a bandeira de interrupção. Quando ele faz isso, o segmento gerado deve ver essa bandeira e encerrar em si.

O thread principal é algo como isto:

final Thread t = new Thread()
{
    @Override
    public void run()
    {
        f();
    }
};
t.start();
try
{
    t.join(time);
    t.interrupt();
    if(t.isAlive())
    {
        t.join(allowance);
        if(t.isAlive())
            throw new Exception();
    }
}
catch(Exception e)
{
    System.err.println("f did not terminate in the alloted time");
}

E o segmento gerado tem um monte do seguinte espalhados por todo o seu código:

if(Thread.interrupted()) return;

Quando estou no modo de depuração, tudo funciona perfeitamente. A bandeira de interrupção é levantada pelo thread principal e é pego pelo segmento gerado. No entanto, no modo de execução normal do segmento gerado parece não receber a bandeira de interrupção, não importa quanto tempo eu definir o subsídio.

Alguém sabe o que estou fazendo de errado?

Nota: eu estou usando o Ubuntu e estou todos juntos de novo para nada Linux. O problema pode estar com o sistema operacional? Eu não testei o código em qualquer outro sistema operacional.

Foi útil?

Solução

Eu sugiro que você considerar o uso de um ExecutorService que é projetado para fazer esse tipo de coisa e poderia ajudá-lo de outras maneiras.

ExecutorService service = Executors.newCachedThreadPool();
Future<ResultType> future = service.submit(new Callable<ResultType() {
   public ResultType call() throws Exception {
      // do soemthing
      return (ResultType) ...;
   }
);
// do anything you like until you need to result.
try {
   ResultType result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException timedOut) {
  // handle exception
  // cancel the task, interrupting if still running.
  result.cancel(true);
} catch (ExecutionException taskThrewAnException) {
  // handle exception
}
// when you have finished with the service, which is reusable.
service.shutdown();

Outras dicas

Aqui estão as minhas suposições:

  • Quando principais chamadas de rosca t.interrupt(); o fio t tem execução já acabado.
  • Quando principais chamadas de rosca t.interrupt(); no fio t não há mais chamadas para verificação da bandeira interrupted().
  • Você recebe a exceção como um resultado da execução do código? Você recebe a exceção você joga em seu código depois de "subsídio" tempo ou você tem algum outro como ThreadInterruptedException ou similar? Tente escrever a mensagem da exceção capturada ...

Você tem aninhados cheques de Thread.interrupted ()? Esse método limpa o sinalizador interrompido, então a segunda chamada retorna false. Você poderia usar isInterrupted () em vez.

Parece que a chamada Thread.interrupted () não está sendo alcançado em f ().

O comportamento diferente que você está vendo nos modos de debug e executá é provável que seja devido a uma condição de corrida.

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