我写了一个简单的服务器。我什么时候运行这个服务器,然后立即使用 uri localhost:7777 在浏览器中打开 3 个选项卡我希望逐个请求线程,在我的情况下它是 3 个
同时线程(每个线程同时启动并在大约同一时间死亡)。
但我在控制台输出中看到第一个线程在 0(本地分钟):11(本地秒)开始,然后第二个线程在 0:11 开始但在读取循环块时停止(为什么?它不是独立线程?)并且仅在之后恢复执行第一个线程和第三个线程的唤醒(0:16)仅在第二个线程死亡(0:21)时运行。
我期待以下时间:
与 Thread-1 连接 0:11 与 Thread-2 连接 0:11 与 Thread-3 连接 0:11 与 Thread-1 断开连接 0:16 与 Thread-2 断开连接 0:16 与 Thread-3 断开连接 0:16
我错过了什么?为什么第二个线程等待第一个线程的唤醒而第三个线程仅在第二个线程死亡后才启动?
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));
}
}
}
程序输出
与 Thread-1 连接 0:11 套接字[地址=/0:0:0:0:0:0:0:1,端口=45416,本地端口=7777] 阅读前 Thread-1 0:11 睡眠线程 1 与 Thread-2 连接 0:11 套接字[地址=/0:0:0:0:0:0:0:1,端口=45419,本地端口=7777] 阅读 Thread-2 之前 0:11 唤醒线程 1 与 Thread-1 断开连接 0:16 睡眠线程 2 唤醒线程 2 与 Thread-2 断开连接 0:21 与 Thread-3 连接 0:21 套接字[地址=/0:0:0:0:0:0:0:1,端口=45424,本地端口=7777] 阅读前 Thread-3 0:21 睡眠线程 3 唤醒线程 3 与 Thread-3 断开连接 0:26