Roscado en Java
-
22-08-2019 - |
Pregunta
Estoy tratando de tener mi hilo principal de desove fuera de un nuevo hilo y, después de algún tiempo, elevar el indicador de interrupción.Cuando lo hace, el generado hilo debería ver que la bandera y terminar en sí.
El hilo principal se ve algo como esto:
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");
}
Y el hilo ha generado un montón de los siguientes dispersos a lo largo de su código:
if(Thread.interrupted()) return;
Cuando estoy en modo de depuración, todo funciona a la perfección.El indicador de interrupción es elevado por el hilo principal y es atrapada por el generado hilo.Sin embargo, en regular el modo de ejecución generado el hilo no parece recibir el indicador de interrupción, no importa cuánto tiempo debo establecer el subsidio.
¿Alguien sabe qué estoy haciendo mal?
Nota:Estoy usando Ubuntu y estoy todo nuevo nada de Linux.Puede que el problema sea con el sistema operativo?No he probado el código en cualquier otro sistema operativo.
Solución
Le sugiero que considere el uso de un ExecutorService que está diseñado para hacer este tipo de cosas y que podrían ayudar de otras maneras.
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();
Otros consejos
Aquí están mis conjeturas:
- Cuando principales llamadas de rosca
t.interrupt();
la t hilo ya ha finalizado la ejecución. - Cuando principales llamadas de rosca
interrupted()
en el hilo t no hay más llamadas para comprobarThreadInterruptedException
bandera. - Se obtiene la excepción como resultado de la ejecución del código? Qué se obtiene la excepción se lanza en su código después de "asignación" tiempo o tienes alguna otra como <=> o similar? Trate de escribir el mensaje de la excepción capturada ...
¿Se han anidado cheques de Thread.interrupted ()? Ese método borra la bandera interrumpido, por lo que la segunda llamada devuelve falso. Se podría utilizar isInterrupted () en su lugar.
Parece como si no se alcanza el Thread.interrupted () en f ().
El diferente comportamiento que está viendo en los modos de depurar y ejecutar es probable que sea debido a una condición de carrera.