Devo preoccuparmi di InterruptedExceptions se non interrompo nulla io stesso?

Sto usando java.util.concurrent.Semaphore in un progetto di hobby. È usato in una class di pool di connessioni che sto scrivendo. Posso usarlo con poca confusione, tranne per questo metodo:

 public void acquire(int permits) throws InterruptedException 

che mi costringe a gestire l’ InterruptedException . Ora, non sono sicuro di cosa significhi “interrompere” una discussione e non lo faccio mai (beh, non esplicitamente in ogni caso) nel mio codice. Questo significa che posso ignorare l’eccezione? Come dovrei gestirlo?

Sì, è necessario preoccuparsi di InterruptedException , proprio come è necessario preoccuparsi per qualsiasi altra eccezione controllata che è necessario lanciare o gestire.

La maggior parte delle volte InterruptedException segnala una richiesta di arresto, molto probabilmente a causa del fatto che il thread che stava eseguendo il codice è stato interrotto .

Nella tua particolare situazione di un pool di connessioni in attesa di acquisire una connessione, direi che si tratta di un problema di cancellazione e devi interrompere l’acquisizione, pulire e ripristinare la bandiera interrotta (vedi sotto).


Ad esempio, se stai utilizzando una sorta di Runnable / Callable esecuzione all’interno di un Executor devi gestire correttamente InterruptedException:

 executor.execute(new Runnable() { public void run() { while (true) { try { Thread.sleep(1000); } catch ( InterruptedException e) { continue; //blah } pingRemoteServer(); } } }); 

Ciò significherebbe che il tuo compito non obbedisce mai al meccanismo di interruzione utilizzato dall’esecutore e non consente una cancellazione / chiusura corretta.

Invece, l’idioma corretto è quello di ripristinare lo stato interrotto e quindi interrompere l’esecuzione:

 executor.execute(new Runnable() { public void run() { while (true) { try { Thread.sleep(1000); } catch ( InterruptedException e) { Thread.currentThread().interrupt(); // restore interrupted status break; } pingRemoteServer(); } } }); 

Risorse utili :

  • Chiudere i thread in modo pulito (specialisti Java)
  • Trattare con InterruptedException (Brian Goetz)

No. InterruptedException viene generato solo se si interrompe il thread da soli. Se non usi tu stesso Thread.interrupt() allora lo Thread.interrupt() come una sorta di “eccezione inaspettata” o lo registrerò come un errore e proseguirò. Ad esempio nel mio codice quando sono costretto a catturare InterruptedException e non chiamo mai interrupt() me stesso, faccio l’equivalente di

 catch (InterruptedException exception) { throw new RuntimeException("Unexpected interrupt", exception); } 

Questo è se è inaspettato. Ci sono molti posti in cui interrompo deliberatamente i miei thread e in quei casi gestisco gli InterruptedException in modo ben definito. Di solito è uscendo da qualsiasi loop in cui mi trovo, pulendo e poi fermando il thread.

I thread possono essere interrotti chiamando Thread.interrupt (). È usato per segnalare con garbo un thread che dovrebbe fare qualcos’altro. Di solito causa operazioni di blocco (ad es. Thread.sleep ()) per tornare prima e lanciare InterruptedException. Se il thread viene interrotto, viene triggersto un flag. Questo flag può essere interrogato tramite la chiamata Thread.isInterrupted ().

Se non si utilizza l’interruzione del thread e si ottiene comunque questa eccezione, è ansible uscire dal thread (e registrare preferibilmente l’eccezione).

In generale, dipende da cosa fa la tua applicazione multi-thread.

Se non sai come gestirlo in un metodo ti suggerisco di dichiararlo nel metodo con l’interruzione di InterruptedException (e il chiamante ecc.)

Se qualcosa che non ti aspetti di verificarsi, lo prenderei e lo racchiuderei in un AssertionError.

Dovresti uscire dal metodo run () dopo aver eseguito la pulizia richiesta dal tuo Thread.
HTH