2013-02-08 13 views
7

Devo essere in grado di inserire un codice di uscita per il thread corrente in esecuzione. Ho lottato con questo per un po ', e alla fine ho si avvicinò con una soluzione qui è un codice simile a quello che sto facendo:Richiamata richiamata thread

public static void injectThreadExitCallback(final Runnable callback) { 
    final curr = Thread.currentThread(); 
    new Thread() { 
     @Override 
     public void run() { 
      try { 
       curr.join(); 
       callback.run(); 
      } catch (InterruptedException ex) { 
       ... logging ... 
      } 
     } 
    }.start(); 
} 

Sembra funzionare bene e fa esattamente quello che sto volendo, la mia unica preoccupazione è, se questo causa qualche perdita o altri effetti collaterali indesiderati, che io possa non vedere.

oppure è perfettamente funzionante, se così è abbastanza utile. Potrei vedere una semplice libreria che può aggiungere dinamicamente il codice di uscita ai thread esistenti.

+1

Sembra buono; solo essere consapevoli del fatto che il callback verrà eseguito su un thread separato. –

+1

Spostare il callback sul blocco 'finally' significa che verrà eseguito se' join' genera un'eccezione che si verificherà * prima * che il thread di destinazione è terminato. Inoltre, join non genererà mai un'eccezione a meno che alcuni agenti esterni non inizino a interrompere tutti i thread. –

+0

Se il thread anonimo che si crea all'interno di questo metodo viene interrotto, è altamente discutibile se il callback debba essere richiamato. Il punto in cui si interrompe un thread è interrompere ciò che sta facendo. Poiché l'unica cosa che questo thread sta facendo è in attesa di richiamare il callback, l'unica ragione per interromperlo sarebbe impedire l'esecuzione del callback. –

risposta

3

È meglio fare

new Thread() { 
    @Override 
    public void run() { 
     try 
     { 
      // Thread logic here 
     } 
     finally 
     { 
      // Thread exit logic here 
     } 
    } 
}.start(); 
+1

buon punto! in questo modo se il filo che sto avvolgendo muore malato riesco ancora a fare quello che devo fare. –

+0

Non è esattamente l'iniezione, vero? Il codice del thread deve essere modificato per incorporare la logica di uscita del thread. (O stai parlando della ristrutturazione del thread di comportamento suggerito dall'OP? –

+0

Penso che stesse dicendo che ho bisogno di spostare la mia callback in caso di eccezioni, penso ... –

0

È possibile spostare la callback.run(); dopo il blocco catch o in final blocco se si vuole essere sicuri che si chiama comunque

+0

In generale, l'unica ragione per interrompere un thread è di farlo smettere di fare ciò che sta facendo. In questo caso, l'unica cosa che sta facendo è aspettare di richiamare la richiamata. Pertanto, si è certi che _non_ desidera assicurarsi che la richiamata sia invocata quando il thread è interrotto! –

+0

Questo è vero, ma dipende dalla logica dell'applicazione che si desidera assicurare che il 'callback' sia chiamato o no. Ad esempio, se il 'callback' sta eseguendo qualche operazione di pulizia, si avrà un motivo legittimo per assicurarsi che venga chiamato anche se il thread viene interrotto. – iTech

2

Non puoi iniettare il codice in un thread in esecuzione a meno che quel thread non stia collaborando attivamente, come ad esempio il thread di invio eventi in AWT, che nella sua radice ha un ciclo che porta fuori Runnables da una coda e li esegue.

Il progetto può introdurre razze di dati in codice che era in precedenza a thread singolo e pertanto non presentava problemi di concorrenza.

Infine, il progetto spreca una preziosa risorsa di sistema (un thread) per non fare altro che attendere il completamento di un altro thread.

Se è necessario per correggere alcuni codici esistenti dall'esterno, potrebbe essere l'unica opzione; in caso contrario, sarebbe meglio fornire un meccanismo esplicito che fosse più efficiente.