2015-04-20 175 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以及相关的类和接口。