Rosqueamento em Java
-
22-08-2019 - |
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.
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 bandeirainterrupted()
. - 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.