2010-08-06 20 views
9

que tienen un hilo:cómo matar un hilo que está esperando una llamada de función de bloqueo en Java?

Thread t = new Thread(){ 
    public void run(){ 
     ServerSocketConnection scn = (ServerSocketConnection) 
       Connector.open("socket://:1234"); 
     // Wait for a connection. 
     SocketConnection sc = (SocketConnection) scn.acceptAndOpen(); 
     //do other operation 
    } 
}; 
t.start(); 

digamos que ningún cliente se conecta al servidor, por lo que este hilo habrá blocked.Now Quiero matar el hilo por encima de t? ¿Cómo puedo matarlo?

Respuesta

7

Thread.interrupt()no interrumpir un hilo bloqueado en un zócalo. Puede intentar llamar al Thread.stop() o Thread.destroy(), pero estos métodos están en desuso (edit: en realidad, ausente en J2ME) y en algunos casos no funcionan, por razones que puede leer sobre here. Como ese artículo menciona, la mejor solución en su caso es cerrar el socket que está bloqueando:

En algunos casos, puede utilizar trucos específicos de la aplicación. Por ejemplo, si un subproceso está esperando en un socket conocido, puede cerrar el socket para hacer que el subproceso vuelva inmediatamente. Desafortunadamente, realmente no hay ninguna técnica que funcione en general. Cabe señalar que en todas las situaciones en las que un hilo en espera no responde a Thread.interrupt, tampoco responde a Thread.stop. Dichos casos incluyen ataques deliberados de denegación de servicio y operaciones de E/S para las cuales thread.stop y thread.interrupt no funcionan correctamente.

+0

¿Estás seguro? ¿En qué api estás mirando? No puedo encontrar Thread.stop() en CLDC o MIDP ... – aioobe

+0

@aioobe: J2SE ... en cualquier caso estoy diciendo * no * use stop() –

+0

bien, porque está hablando de java- aquí ... – aioobe

0

Puede llamar al thread.interrupt(). Esto lanzará un InterruptedException en su hilo

+0

¿Estás seguro? acceptAndOpen no está declarado para lanzar InterruptedException – aioobe

+0

esta es una Excepción de tiempo de ejecución que no es generada por acceptAndOpen sino por Thread-class. –

+1

¿En qué API está interrumptedException una excepción de tiempo de ejecución? Usted tiene una URL? – aioobe

0

Haz el hilo principal MONITOR THREAD (de donde engendras este nuevo hilo) join() para este hilo. Si después de un tiempo de espera determinado, este hilo no se "une", entonces puede ignorar (anular) este hilo. Esto le dará una funcionalidad adicional que agrega tiempo de espera para bloquear el hilo.

0

En el hilo principal (cuando desee finalizar el hilo de aceptación), llame al scn.close(). El acceptAndOpen debe arrojar un IOException, que puede capturar y luego terminar el thread de aceptación correctamente.

ServerSocketConnection scn = 
    (ServerSocketConnection) Connector.open("socket://:1234"); 

Thread t = new Thread(){ 
    public void run(){ 
     // Wait for a connection. 
     try { 
      SocketConnection sc = (SocketConnection) scn.acceptAndOpen(); 
      //do other operation 
     } catch (IOException e) { 
      // Log the exception 
     } 
    } 
}; 

t.start(); 

// ... 

// Somewhere else... 
// Cancel the acceptAndOpen. 
scn.close(); 

Una buena idea sería introducir un mecanismo de sincronización para que no se cierre la derecha después de la toma de acceptAndOpen atravesó.

0

creo que sólo se necesita para cerrar la conexión - por lo que simplemente hacer scn un campo de la rosca y poner en práctica:

public void stop() { 
    scn.close(); 
} 

y codificar su principal método para salir con gracia en IOException u otra indicación de que has terminado (como probablemente ya lo has hecho).

0

Acabo de llegar a esta página buscando la misma respuesta.He encontrado una manera de cerrar Hilos y esto es lo que hago para poner fin al servidor:

private Thread serverThread; 

public void setUp(){ 
    //Run the server 
    serverThread = new Thread() { 
     public void run() { 
      try { 
       new Server(); //it calls acceptAndOpen() here 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    }; 
    serverThread.start(); 
} 

public void tearDown() { 
    serverThread = null; 
    System.gc(); 
} 

Básicamente, hacer que su referencia a su nula hebra del servidor, y luego dejar que el recolector de basura limpiar los recursos (que es su servidor) para ti.

Nota sin embargo: Esto está lejos de ser perfecto, que nunca debería depender de GC para hacer su trabajo, pero parece que funciona cada vez que he intentado

Cuestiones relacionadas