Java 意外的多线程结果和计时
我写了一个简单的服务器。我什么时候运行这个服务器,然后立即在浏览器中打开3个选项卡,uri为localhost:7777我希望是请求线程,在我的例子中是3 同时线程每个线程在同一时间开始,并在大约同一时间死亡 但我在控制台输出中看到,第一个线程在0分11秒开始,然后第二个线程在0分11秒开始,但停止了为什么?它不是独立线程?在读循环块 只有在第一个线程的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 我错过了什么?为什么第二个线程等待第一个线程的唤醒,而第三个线程仅在第二个线程死亡后启动Java 意外的多线程结果和计时,java,multithreading,sockets,Java,Multithreading,Sockets,我写了一个简单的服务器。我什么时候运行这个服务器,然后立即在浏览器中打开3个选项卡,uri为localhost:7777我希望是请求线程,在我的例子中是3 同时线程每个线程在同一时间开始,并在大约同一时间死亡 但我在控制台输出中看到,第一个线程在0分11秒开始,然后第二个线程在0分11秒开始,但停止了为什么?它不是独立线程?在读循环块 只有在第一个线程的0:16唤醒后才恢复执行 第三个线程只有在第二个线程死0:21时才运行 我期待以下时间: Connected with Thread-1 0:1
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,在第一个请求完成之前,它不会发送第二个请求,在第一个请求完成之前,它甚至不会连接第三个请求。我猜这是为了对服务器好一点,不让它过载,或者其他什么