Java: Articole Închiderea bruscă a aplicației Java: cum să evitați?
În multe cazuri, sperați că utilizatorul va închide aplicația într-o manieră "normală" pentru dvs. De exemplu, în primul caz, îi puteți furniza componenta JButton, după ce faceți clic pe care se efectuează operațiile finale necesare și aplicația iese direct. În mod alternativ, puteți închide un handler de evenimente pentru ferestre care gestionează evenimentul de închidere a ferestrei. Tomcat folosește, de asemenea, un fișier special, care poate fi executat atunci când aplicația este închisă corespunzător. Cu toate acestea, este bine cunoscut faptul că utilizatorii nu termină adesea corect cererile. Pot face cu orice vor. În plus, utilizatorul poate închide consola sau poate completa sesiunea cu sistemul de operare, lăsând aplicația deschisă.
În Java, o mașină "virtuală" iese în două cazuri: în primul rând, când aplicația iese în mod normal, adică A fost apelată metoda System.exit sau când ultimul thread nu era un daemon. În al doilea rând, atunci când un utilizator întrerupe brusc un mașini „virtuale“, de exemplu, prin apăsarea combinației de taste Ctrl + C sau părăsesc sistemul fără a închide aplicația Java pe bază de pre-operare.
Din fericire, mașina virtuală urmează următoarea secvență de acțiuni în două faze înainte de descărcare:
- Mașina virtuală rulează toate capcanele de închidere înregistrate, dacă există. Capcanele de închidere sunt firele care sunt înregistrate utilizând clasa Runtime. Toate aceste capcane vor fi lansate și vor funcționa în paralel până când toate își vor termina activitatea.
- O mașină virtuală apelează toate operațiile finalizate definite (dacă există).
În acest articol, vom analiza primul punct, deoarece permite programatorului să plictisească mașina "virtuală" Java cu operațiile necesare pentru a finaliza aplicația. Capcanele de închidere sunt doar instanțe ale clasei de mostenitori ai clasei Thread. Pentru a crea o astfel de capcană, trebuie să faceți următoarele:
- Descrieți o clasă care moștenește din clasa Thread.
- Implementați implementarea metodei de rulare a acestei noi clase. Această metodă conține codul care va fi executat atunci când mașina "virtuală" se termină, indiferent dacă aplicația a fost finalizată în mod normal sau nu.
- Asociați clasa shutdown-trap cu aplicația dvs.
- Înregistrați o capcană utilizând metoda addShutdownHook a instanței curente a clasei Runtime.
După cum probabil ați observat, nu este necesar să rulați noul fir creat, deoarece ați rula o altă clasă care a moștenit Thread. Preocuparea pentru rularea acestui fir cade pe mașina "virtuală", care, atunci când se apropie de secvența de oprire, va lansa toate firele înregistrate ale capcanelor.
Codul din listare 1 reprezintă o clasă simplă ShutdownHookDemo și o subclasă de Thread-ShutdownHook. Rețineți că metoda de rulare a clasei ShutdownHook trimite pur și simplu linia "Închidere" către consola. Desigur, puteți insera absolut orice cod pe care trebuie să-l executați în momentul finalizării aplicației.
După pornirea clasei publice, se numește metoda de pornire. Metoda de pornire creează o capcană de închidere și o înregistrează în instanța curentă a clasei Runtime
Apoi, programul așteaptă ca utilizatorul să apese pe Enter.
Când utilizatorul apasă tasta Enter, programul se oprește. Cu toate acestea, înainte de ieșire, mașina "virtuală" pornește o capcană de închidere înregistrată, care la rândul ei imprimă linia "Închidere".
Ca un exemplu următor, vom examina o aplicație simplă Swing, a cărei clasă principală se numește MySwingApp. Această aplicație creează un fișier temporar la pornire. Când se închide, fișierul trebuie șters. Codul pentru această aplicație este afișat în listare 2.
Listing 2.
La pornire, această aplicație apelează metoda inițializării. Această metodă, la rândul său, creează un fișier temporar în directorul curent numit temp.txt.
Când utilizatorul închide această aplicație, fișierul temporar trebuie șters. În acest caz, nu putem decât să sperăm că utilizatorul va face clic pe butonul Ieșire, iar făcând clic pe el, va fi apelată metoda de închidere, care va șterge fișierul temporar. Cu toate acestea, fișierul temporar nu va fi șters dacă utilizatorul iese din program utilizând butonul de sistem X al ferestrei aplicației sau în alt mod.
Lista 3 arată versiunea aceleiași aplicații care rezolvă această problemă. Noua versiune a aplicației modifică codul din Lista 2, instalând opritorul de închidere. Clasa acestei capcane este definită ca fiind clasa interioară a clasei principale a aplicației. Astfel, accesează toate câmpurile și metodele din clasa principală. În lista 3, metoda de rulare a clasei de capcane pur și simplu numește metoda de închidere a clasei principale. Acest lucru asigură că este apelat când aplicația se termină.
Listarea 3.
Observați metoda inițializării. Primul lucru pe care îl face este să creeze o instanță a clasei interne MyShutdownHook care moștenește clasa Thread.
Acum, după obținerea unei instanțe a clasei MyShutdownHook, o înregistrăm în Runtime folosind metoda addShutdownHook:
Restul metodei initialize se potrivesc exact aceleiași metode din listare 2. În această parte este creat un fișier temporar și este afișată linia "Crearea fișierului temporar".
Încercați să rulați această mică aplicație Swing. Asigurați-vă că fișierul temporar este șters în orice caz, indiferent de modul în care închideți aplicația.
Capcanele de închidere pe care le-am acoperit în acest articol sunt, de fapt, singura soluție corectă la problema executării unui cod la sfârșitul aplicației. Și din moment ce nu puteți fi siguri cum va închide utilizatorul de această dată, utilizarea lor va face viața mult mai ușoară pentru dvs., asigurându-vă că sunt îndeplinite regulile de terminare a programului pe care le-ați stabilit.
Avertizare. mysql_connect () [function.mysql-connect]: Nu se poate conecta la serverul MySQL local prin socket '/tmp/mysql.sock' (2), în /pub/home/javaport/javaportal/books/show2b.php pe linia 11
Avertizare. mysql_db_query () [function.mysql-db-interogare]: Nu se poate conecta la serverul MySQL local prin socket '/tmp/mysql.sock' (2), în /pub/home/javaport/javaportal/books/show2b.php pe linia 19
Avertizare. mysql_db_query () [function.mysql-db-interogare]: Un link către serverul nu a putut fi stabilită în /pub/home/javaport/javaportal/books/show2b.php pe linia 19
Avertizare. mysql_fetch_array (): furnizat argumentul nu este o resursă valabil rezultat MySQL în /pub/home/javaport/javaportal/books/show2b.php pe linia 30
Aflați la ce vă gândiți cu adevărat acum.
[a apărut o eroare în timpul procesării acestei directive]
Avertizare. mysql_connect () [function.mysql-connect]: Nu se poate conecta la serverul MySQL local prin socket '/tmp/mysql.sock' (2), în /pub/home/javaport/javaportal/news/worldnews.php pe linia 91
Avertizare. mysql_db_query () [function.mysql-db-interogare]: Nu se poate conecta la serverul MySQL local prin socket '/tmp/mysql.sock' (2), în /pub/home/javaport/javaportal/news/worldnews.php pe linia 93
Avertizare. mysql_db_query () [function.mysql-db-interogare]: Un link către serverul nu a putut fi stabilită în /pub/home/javaport/javaportal/news/worldnews.php pe linia 93
Avertizare. mysql_fetch_array (): furnizat argumentul nu este o resursă valabil rezultat MySQL în /pub/home/javaport/javaportal/news/worldnews.php pe linia 95