簡単なサーバーを書きました。このサーバーを実行し、ブラウザで 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