1. Primeiro olhe para o seguinte código
importar java.io.fileInputStream; public class ttt {public static void main (string [] args) lança exceção {for (int i = 0; i <10; i ++) {final string threadid = "thread_" + i; thread = thread = thread (new runnable () {public void run () {Sistema.out.; = new FileInputStream ("/opt/test.log"); Thread.sleep (60 * 1000);} Catch (Exceção ex) {ex.PrintStackTrace ();} System.out.println (ThreadID + "Stopped!");}}); Thread.start ();};2. Compile e execute esta classe no Linux e, em seguida, use o comando linux/usr/sbin/lsof -p <pid> para visualizar as informações do arquivo abertas por este programa.
$/usr/sbin/lsof -p `ps -ef | grep 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. 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 253. 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/est.Gjava /opt/test.logSeja durante ou após 10 threads em execução, os resultados da visualização usando o comando LSOF são os mesmos. Você pode ver que 10 fluxos de arquivo não estão fechados.
3. Eu fiz algumas alterações nesse código abaixo, ou seja, depois que o tópico é executado, todos os threads são definidos como nulos, como segue
importar java.io.fileInputStream; importar java.util.ArrayList; importar java.util.list; public class ttt {public static void main (string [] args) lança excepção {list <shread> threads = new ArrayList <hread> (); para (int i = 0; i <10; Runnable () {public void run () {System.out.println (threadId + "iniciado!"); Tente {FileInputStream fis = new FileInputStream ("/opt/test.log"); Thread.Sleep (60 * 1000);} Catch (Exceção ex) {ex.PrintStack (); "parado!");}}); thread.start (); threads.add (thread);} thread.sleep (2 * 60 * 1000); para (threads: threads: threads) {thread = null;} system.out.println ("limpe o threads!); Novamente, use o LSOF para visualizar durante e depois que os 10 threads forem executados e os resultados ainda são semelhantes e ainda existem 10 fluxos de arquivo que não estão fechados.
Fiz algumas alterações novamente, depois de definir todos os threads como nulos, adicione (ou exorto a JVM) a fazer algumas operações do GC, como segue:
importar java.io.fileInputStream; importar java.util.ArrayList; importar java.util.list; public class ttt {public static void main (string [] args) lança excepção {list <shread> threads = new ArrayList <hread> (); para (int i = 0; i <10; Runnable () {public void run () {System.out.println (threadId + "iniciado!"); Tente {FileInputStream fis = new FileInputStream ("/opt/test.log"); Thread.Sleep (60 * 1000);} Catch (Exceção ex) {ex.PrintStack (); "parado!");}}); thread.start (); threads.add (thread);} thread.sleep (2 * 60 * 1000); para (threads: threads) {thread = null;} system.out.println ("limpe os threads!); system.gc (); Gc! "); Thread.sleep (10 * 60 * 1000);}}Use o LSOF para visualizar novamente, e você ainda pode ver que 10 fluxos de arquivo estão abertos durante a corrida, mas após o "GC terminado!", O resultado é que os 10 fluxos de arquivo estão fechados.
Finalmente, simplesmente excluí as declarações que definiram o thread como NULL, e os resultados da execução também são consistentes com os resultados da execução de operações GC acima.
No final, para os fluxos de arquivos de IO que estão abertos e não fechados na JVM, reciclarão todos eles quando não forem mais usados quando estiverem fazendo GC completo na próxima vez, mas ainda não é bom deixar a JVM fazer essas coisas. O mesmo velho ditado é fazer suas próprias coisas.