2015-04-20 211 views
0

我寫了一個多線程處理多個連接的客戶端/服務器應用程序。我有一個接受傳入連接的父類,以及接受接收的套接字並接收數據等的內部類。Java線程/運行停止

我注意到雖然每個線程都在「完成」,並且正在調用thread.join(),但分配給進程的內存隨着每個連接的增加而不斷縮小。

我不認爲我現在能夠共享很多代碼,但我有類似的東西來嘗試結束這些線程。我也確信跑步方法正在完成。 ThreadHandler是包含線程及其Runnable的內部類。在run()完成後,IsRunning()將返回true。

private static void cleanupThreads(ArrayList<ThreadHandler> threads){ 

    //find all of the non-running threads and join them 

    for(int i = 0; i < threads.size(); i++){ 

     //get the Handler and check whether it's running 
     ThreadHandler tmpThread = threads.get(i); 
     Handler tmpHandler = tmpThread.getHandler(); 
     if(!tmpHandler.isRunning()){ 
      //time to die 
      threads.remove(i); 
      try{ 
       tmpThread.getThread().join(); 
       System.out.println("thread joined"); 
      }catch(InterruptedException e){ 

      } 
     } 
    } 
} 

當預先聲明〜10個線程並將它們分配給Connections時,是否有更好的選擇?現在,調用System.gc()可以減少內存負載,但這通常是不好的做法。

+2

你可以顯示用於接受連接和創建線程的代碼嗎?這可能更相關。另外,你爲什麼認爲這是一個記憶問題?您所描述的行爲或多或少都是正常的,並不一定表示內存問題,除非您獲得OOME。 – Necreaux

+2

我不會說越來越大的內存佔用是一個問題,除非它是(例如OutOfMemoryError)。那麼,這是一個問題嗎?你是否收到錯誤?手動調用System.gc並看到內存減少表示沒有「泄漏」 – copeg

+0

用於接受連接的代碼本質上如下所示。我無法發佈run()方法。 '插座ClientSocket的= socket.accept();'' 處理程序處理程序新=處理程序(ClientSocket的);'' 線程線程=新主題(處理程序);'' thread.start();' I」我沒有得到一個OOME,但我正在運行tasklist,並注意到在幾分鐘的單元測試後,Java進程已經升到了大約200MB。 – MarkDacek

回答

1

當預先聲明〜10個線程並將它們分配給Connections時,是否有更好的選擇?

不,這通常是一個很好的想法因爲創建和銷燬線程是要比重新使用它們更加昂貴。這個想法被稱爲線程池,並且Java標準庫已經爲您實現了一個;查看java.util.concurrent.ThreadPoolExecutor的javadoc以及相關的類和接口。