1. Сначала посмотрите на следующий код
Импорт java.io.fileinputStream; открытый класс ttt {public static void main (string [] args) бросает исключение {for (int i = 0; i <10; i ++) {final String threadid = "threat_" + i; Thread Think = new Runnable () {public void run () {System.out.println (ThreadId + "raveln ranpeam file -inpure ()") = new FileInputStream ("/opt/test.log"); thread.sleep (60 * 1000);} Catch (Exception ex) {ex.printStackTrace ();} System.out.println (ThreadId + "остановлен!2. Скомпилируйте и запустите этот класс на Linux, а затем используйте команду Linux/usr/sbin/lsof -p <pid>, чтобы просмотреть информацию о файле, открываемая этой программой.
$/usr/sbin/lsof -p `ps -ef | Греп Java | grep ttt | awk '{print $ 2}' `| grep "test.log" java 21562 fkong 3r reg 253,0 0 35471424 /opt/test.logjava 21562 fkong 4r reg 253,0 0 35471424 /opt/test.logjava 21562 fkong 5r Reg 253,0 0 35471424142414241424142414241424142414241424142414241424142414241424142414241424142414241424142414241424142414241424142414241424142414241. 21562 fkong 6r REG 253,0 0 35471424 /opt/test.logjava 21562 fkong 7r REG 253,0 0 35471424 /opt/test.logjava 21562 fkong 8r REG 253,0 0 35471424 /opt/test.logjava 21562 fkong 11r REG 253,0 0 35471424 /Opt/test.logjava 21562 Fkong 11r Reg 253,0 0 35471424 /Opt/test.logjava 21562 FKONG 11R REG 253,0 0 35471424 /OPT/LOGJAVA 21562 FKONG 12.024444424 /Opt/Logjava 21562 FKONG 2534744444444424 /OPT/Logjava 21562 FKong 254747444424 /Opt/Logjava 21562 FKong 2547444424 /opt/Logjava 21562 FKong 25474424 /opt/logjava 21562. /opt/test.logБудь то во время или после 10 запущенных потоков, результаты просмотра с использованием команды LSOF одинаковы. Вы можете видеть, что 10 файловых потоков не закрыты.
3. Я внес несколько изменений в этот код ниже, то есть после выполнения потока все потоки установлены на NULL, следующим образом
Импорт java.io.fileinputStream; import java.util.arraylist; import java.util.list; public class ttt {public static void main (string [] args) вызывает исключение {list> thints = new restraylist <Thint> (); для (int i = 0; i <10; i ++) {final String Thinkid = Thread_ "+I; Runnable () {public void run () {system.out.println (threadid + "start!"); Try {fileInputStream fis = new FileInputStream ("/opt/test.log"); thread.sleem (60 * 1000);} catch (exception ex) {ex.printStackTrace ();} System.out.out.print. «Остановлен!»);}}); Thread.Start (); Threads.Add (Thread);} Thread.sleep (2 * 60 * 1000); for (потока: потоки) {Thread = null;} System.out.println ("Очистить потоки!"); Thread.sleep (10 * 60 * 1000); Опять же, используйте LSOF для просмотра во время и после запуска 10 потоков, и результаты все еще похожи, и все еще есть 10 потоков файлов, которые не закрыты.
Я внес несколько изменений снова, после установки всех потоков в NULL, добавить (или призвать JVM) сделать несколько операций GC, следующим образом:
Импорт java.io.fileinputStream; import java.util.arraylist; import java.util.list; public class ttt {public static void main (string [] args) вызывает исключение {list> thints = new restraylist <Thint> (); для (int i = 0; i <10; i ++) {final String Thinkid = Thread_ "+I; Runnable () {public void run () {system.out.println (threadid + "start!"); Try {fileInputStream fis = new FileInputStream ("/opt/test.log"); thread.sleem (60 * 1000);} catch (exception ex) {ex.printStackTrace ();} System.out.out.print. «Остановлен!»);}}); Thread.Start (); Threads.Add (Thread);} Thread.sleep (2 * 60 * 1000); для (потока потока: потоки) {Thread = null;} System.out.println («Очистить потоки!»); System.gc (); System.gc (); GC! "); Thread.sleep (10 * 60 * 1000);}}Используйте LSOF для просмотра снова, и вы все еще можете увидеть, что 10 файловых потоков открыты во время работы, но после «Завершенного GC!» В результате 10 -й потоки файлов закрыты.
Наконец, я просто удалил операторы, которые устанавливают потока в NULL, и результаты прогона также согласуются с результатами выполнения операций GC выше.
В конце концов, для тех, кто открыт и не закрыт в JVM, будут перерабатывать их все, когда они больше не используются, когда в следующий раз они выполнят полный GC, но все же нехорошо позволить JVM делать эти вещи. Та же самая старая поговорка - это делать свои вещи.