0

我在我的 Android 应用程序中获得了服务器线程,当用户决定关闭它时需要正确处理它。我选择接受()客户端的非阻塞 ServerSocketChannel。
得到了这个问题

public class SocketServer extends Thread
{
  private static final String LOG_TAG  = "SocketServer";
  private boolean isRunning  = false;
  private ServerSocketChannel listener = null;

public void _stop()
{
  this.isRunning = false;
}

public void _start()
{
  this.isRunning = true;
  this.start();
}

private void free()
{
  try
  {
    listener.close();
  }
  catch (IOException e)
  {
    //Error handle
  }
  listener = null;
}

public SocketServer(int port)
{
  super();
  try
  {
     listener = ServerSocketChannel.open();
     listener.configureBlocking(false);
     listener.socket().bind(new InetSocketAddress(port));
  }
  catch (IOException e)
  {
    //Error handle
  }
}

public void run()
{
  SocketChannel client = null;
  while(isRunning)
  {
    try
    {
      client = listener.accept();//GC going mad
    }
     if(client != null)
                Log.i(LOG_TAG, "ACCEPTED CLIENT");

    catch (IOException e)
    {
      //Error handle
    }
  }
    free();
}  

我正在做的就是接受新客户端 -因为没有传入连接而变为,然后再做一次,直到服务器停止。
ServerClient客户端在启动时为 null ,如果没有可用连接,则由 accept()分配为null 。

但是Java的垃圾收集器认为客户端以某种方式通过accept()或accept()以某种方式初始化分配了一些内存,GC在每个while循环后都会清理这些内存。
如果注释accept() 行(例如什么都不做)根本就没有GC,那么就在accept() 中出现问题。

在我看来,这完全不对。

PS如果有什么方法可以打破阻塞ServerSocket accept()/ Socket read() 状态并正确退出,请告诉我。

PS 2对于 Socket,对 SocketChannel 的 socket() 进行写入/读取是否安全,它会阻塞线程吗?

4

1 回答 1

1

Java 中的许多操作在内部创建临时对象来完成它们的工作。

使用阻塞的 SocketServer 会好得多。这样,它创建的对象仅基于每个接受的套接字,而不是基于每个尝试。

我建议您首先为每个连接使用一个(或两个)线程来实现阻塞 NIO。如果随后您发现线程数存在性能问题,请尝试使用具有非阻塞 NIO 的 Selector。

于 2012-08-03T13:26:28.010 回答