Recent am întâlnit încă o dată procesarea incorectă a InterruptedException în Java. InterruptedException este verificată excepția generată de multe metode standard de bibliotecă care blochează firul de execuție. Acestea includ: versiuni întreruptibile ale lui lock'ov. metoda Thread.sleep (). unele operații privind blocarea cozilor. unele operații pe canale și altele.
La miezul său, InterruptedException semnalează că firul cere să-și finalizeze operațiunea. În acest caz, nu vi se cere să vă terminați imediat lucrarea. Vi se cere să ieșiți corect. Aceasta poate dura ceva timp.
Firul este întrerupt utilizând metoda Thread.interrupt (). Există două moduri în care JVM notifică firul că acesta este întrerupt. Primul este, de fapt, o InterceptareExcepție. Al doilea este steagul fluxului INTERRUPT. care pot fi obținute utilizând metoda Thread.isInterrupted (). Ignorarea celei de-a doua metode de semnalizare a întreruperii este o eroare tipică.
Acest cod este incorect, deoarece "apasă" semnalul de întrerupere. Dacă acest cod este executat în pool-ul de fire, atunci pe această sarcină muncitorul (care va sunat) va trebui să finalizeze executarea sarcinilor, deoarece firul a primit o întrerupere. Dar acest lucru nu se va întâmpla deoarece semnalul de întrerupere a fost interceptat de codul de mai sus. De regulă, acest lucru se explică prin faptul că, după trimiterea semnalului de ucidere către mașina java, acesta are totuși fire de lucru, datorită cărora JVM nu-și poate finaliza activitatea. În acest caz, singura ieșire este kill -9.
Următorul cod este, de asemenea, incorect, deoarece "mascăm" întreruperea într-o situație excepțională de alt tip. Astfel, acesta nu permite apelantului să repare situația de întrerupere.
Codul corect va arăta astfel.
Aici am prins InterruptedException și expunem pavilionul fluxului care semnalizează întreruperea.
Politica de întrerupere face parte din contract. Dacă declarați că InterruptedException poate să nu apară în timpul executării metodei, dar în același timp de asteptare această metodă aruncă o excepție, ar trebui să convertiți corect InterruptedException în fluxul de pavilion de întrerupere. Același lucru este valabil și pentru partea apelantă. Dacă apelați o metodă care generează contractul InterruptedException. atunci ar trebui să vă așteptați ca metoda să vă anunțe o întrerupere prin excepție. Dacă nu, atunci cu ajutorul unui steag.
Un cititor atent ar putea întreba întrebarea: "De ce două moduri de semnalizare? Nu este posibil să o gestionați? ".
De ce am nevoie de Thread.isInterrupted ()?
InterruptedException este incomod, deoarece este verificată excepția. Acest lucru înseamnă că compilatorul vă obligă fie să îl procesați pe plan local, fie să îl specificați în contract. Dacă nu puteți specifica InterruptedException în contract (de exemplu, în cazul în care contractul de interfață implementiruete InterruptedException Necunoscut) de pavilion flux este singura modalitate de a transfera apelantului să întrerupă informații.
De ce am nevoie de o InterruptedException?
InterruptedException vă permite să întrerupeți un flux care deja execută un apel de blocare. Dacă metoda este deja executată, atunci există o singură modalitate de ao abroga fără a reveni la nicio valoare și fără a vi se încălca contractul - generați o excepție. În acest caz, valoarea returnată a metodei este pur și simplu nedefinită.