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();
}  

私がしているのは、新しいクライアントを受け入れることだけです-着信接続がないためにnullになり、サーバーが停止するまでそれを繰り返します。
ServerClientクライアントは開始時に null であり、利用可能な接続がない場合は accept() によってnullに割り当てられます。

しかし、Java のガベージ コレクターは、accept() または accept() によってどのクライアントが初期化されているかを何らかの方法で認識し、GC が while ループのたびにクリーンアップするメモリを何らかの方法で割り当てます。
accept() 行にコメントを付けると (たとえば、何もしない)、GC がまったくないため、正確に accept() に問題があります。

私の意見では、これはまったく正しくありません。

PSブロッキングServerSocket accept()/ Socket read() 状態を解除して適切に終了する方法がある場合は、教えてください。

PS 2ソケットに関して SocketChannel socket() への書き込み/読み取りは安全ですか?スレッドをブロックしますか?

4

1 に答える 1

1

Java の多くの操作では、作業を行うために一時オブジェクトが内部的に作成されます。

ブロッキング SocketServer を使用する方がはるかに優れています。この方法で作成されるオブジェクトは、試行ごとではなく、受け入れられたソケットごとにのみ作成されます。

最初に、接続ごとに 1 つ (または 2 つ) のスレッドでブロッキング NIO を実装することをお勧めします。その後、使用しているスレッドの数にパフォーマンスの問題があることがわかった場合は、ノンブロッキング NIO でセレクターを使用してみてください。

于 2012-08-03T13:26:28.010 に答える