我写了一个简单的服务器。我什么时候运行这个服务器,然后立即在浏览器中使用 uri localhost:7777 打开 3 个选项卡,我希望按请求线程,在我的情况下它是 3
同时线程(每个线程同时启动并大约在同一时间终止)。
但是我在控制台输出中看到第一个线程在 0(本地分钟):11(本地秒)开始,然后第二个线程在 0:11 开始但在读取循环 block 时停止(为什么?它不是独立线程?) 并仅在第一个线程唤醒(0:16)后恢复执行 第三个线程仅在第二个线程死亡时运行(0:21)。
我预计以下时间:
Connected with Thread-1 0:11 Connected with Thread-2 0:11 Connected with Thread-3 0:11 Disconnect with Thread-1 0:16 Disconnect with Thread-2 0:16 Disconnect with Thread-3 0:16
What I missed? Why second thread waits awaking of first thread and third thread starts only after death of second thread?
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));
}
}
}
程序输出
Connected with Thread-1 0:11 Socket[addr=/0:0:0:0:0:0:0:1,port=45416,localport=7777] Before reading Thread-1 0:11 Asleep Thread-1 Connected with Thread-2 0:11 Socket[addr=/0:0:0:0:0:0:0:1,port=45419,localport=7777] Before reading Thread-2 0:11 Awake Thread-1 Disconnect with Thread-1 0:16 Asleep Thread-2 Awake Thread-2 Disconnect with Thread-2 0:21 Connected with Thread-3 0:21 Socket[addr=/0:0:0:0:0:0:0:1,port=45424,localport=7777] Before reading Thread-3 0:21 Asleep Thread-3 Awake Thread-3 Disconnect with Thread-3 0:26
最佳答案
据我所知,您的代码没有任何问题。然而,同样的事情也发生在我身上,所以我尝试自己运行它,同时使用 tcpdump
监控网络流量,看来这只是浏览器在玩把戏,而不是你的代码。
我使用的是 Chromium,在第一个请求完成之前它不会发送第二个请求,甚至在此之前它也不会连接第三次。我猜它是想通过不让服务器重载或者其他什么方式来善待服务器。
关于java - 意外的多线程结果和计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19074762/