1

簡単なサーバーを書きました。このサーバーを実行し、ブラウザで uri localhost:7777 を使用して 3 つのタブをすぐに開くと、リクエストごとにスレッドが期待されます。私の場合は、3 つの
同時スレッドです (すべてのスレッドが同時に開始され、ほぼ同時に終了します)。

しかし、コンソール出力では、最初のスレッドが 0(ローカル分):11(ローカル秒) に開始され、次に 2 番目のスレッドが 0:11 に開始されましたが、ループ ブロックの読み取り時に停止し (なぜ独立したスレッドではないのですか?)、実行が再開されたことがわかります。最初のスレッドと 3 番目のスレッドの awaking(0:16) は、2 番目のスレッドが終了したとき (0:21) にのみ実行されます。

次のタイミングを期待しています:

スレッド-1とつながる 0:11
スレッド-2 とつながる 0:11
スレッド-3 0:11 とつながる
Thread-1 との接続を切断する 0:16
Thread-2 との接続を切断する 0:16
Thread-3 との切断 0:16

私が逃したものは何ですか?2 番目のスレッドが最初のスレッドの起動を待機し、3 番目のスレッドが 2 番目のスレッドの終了後にのみ開始するのはなぜですか?

public class Starter {

    public static void main(String args[]){

    int port = 7777;
        try {

            final ServerSocket socket = new ServerSocket(port);
            new Thread(new ThreadPool(socket)).start();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}




public class ThreadPool implements Runnable{

protected ServerSocket socket;

public ThreadPool(ServerSocket socket){
    this.socket = socket;
}

@Override
public void run() {

    final ExecutorService executors = Executors.newCachedThreadPool();

    while(true){
        try {
            final Socket acceptedSocket = this.socket.accept();
            //executors.execute(new ThreadWork(acceptedSocket));
            new Thread(new ThreadWork(acceptedSocket)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
}



public class ThreadWork implements Runnable {

protected final Socket clientSocket;

public ThreadWork(Socket clientSocket){
    this.clientSocket = clientSocket;
}

@Override
public void run() {
    try {
        System.out.println("Connected with " + java.lang.Thread.currentThread().getName() + " " + ((System.currentTimeMillis() / 1000*60) % 60) + ":" + ((System.currentTimeMillis() / 1000) % 60));
        System.out.println("   " + clientSocket.toString());

        InputStream sin = clientSocket.getInputStream();
        OutputStream sout = clientSocket.getOutputStream();

        BufferedReader in = new BufferedReader(new InputStreamReader(sin));
        OutputStreamWriter out = new OutputStreamWriter(sout);

        String line =
                "HTTP/1.1 200 OK\n"  +
                        "Date: Thu, 19 Feb 2009 12:27:04 GMT\n"       +
                        "Server: Apache/2.2.3\n"                         +
                        "Last-Modified: Wed, 18 Jun 2003 16:05:58 GMT\n"       +
                        "Content-Type: text/html\n"             +
                        "Content-Length: 115\n"      +
                        "Accept-Ranges: bytes\n"      +
                        "Connection: close\n"  +
                        "\r\n" +
                        "<html><head><title>Hello</title></head><body>It Works!</body></html>\n";

        String requestLine;

        System.out.println("      Before reading " + java.lang.Thread.currentThread().getName() + " " + ((System.currentTimeMillis() / 1000*60) % 60) + ":" + ((System.currentTimeMillis() / 1000) % 60));
        while((requestLine = in.readLine()) != null) {
            if(requestLine.isEmpty()){
                break;
            }
        }
        System.out.println("         Asleep " + java.lang.Thread.currentThread().getName());
        java.lang.Thread.sleep(5000);
        System.out.println("         Awake " + java.lang.Thread.currentThread().getName());
        out.write(line);
        out.flush();
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        try {
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        System.out.println("Disconnect with " + java.lang.Thread.currentThread().getName() + " " + ((System.currentTimeMillis() / 1000*60) % 60) + ":" + ((System.currentTimeMillis() / 1000) % 60));
    }
}
}

プログラム出力

スレッド-1とつながる 0:11
   ソケット[addr=/0:0:0:0:0:0:0:1,port=45416,localport=7777]
      スレッド-1 0:11 を読む前に
         スリープスレッド-1
スレッド-2 とつながる 0:11
   ソケット[addr=/0:0:0:0:0:0:0:1,port=45419,localport=7777]
      スレッド-2 0:11 を読む前に
         覚醒スレッド-1
Thread-1 との接続を切断する 0:16
         スリープスレッド-2
         覚醒スレッド-2
Thread-2 との接続を切断する 0:21
03 スレッド-3とつながる 0:21
   ソケット[addr=/0:0:0:0:0:0:0:1,port=45424,localport=7777]
      スレ3を読む前に 0:21
         スリープスレッド-3
         覚醒スレッド-3
Thread-3 との切断 0:26
4

1 に答える 1

0

私が見る限り、あなたのコードには何の問題もありません。ただし、同じことが私にも起こるので、でネットワークトラフィックを監視しながら自分で実行してみましたtcpdump.コードではなく、単にブラウザがトリックをしているようです.

私はChromiumを使用していますが、最初のリクエストが完了するまで2番目のリクエストを送信せず、それまで3回目のリクエストも送信しません。サーバーに過負荷をかけないようにするなどして、サーバーに優しくしようとしていると思います。

于 2013-09-29T05:48:56.420 に答える