1
我寫了一個簡單的服務器。我什麼時候運行這個服務器,然後立即用uri localhost在瀏覽器中打開3個選項卡:7777我希望按照請求線程,在我的情況下,它是同時線程(每個線程同時開始並在大約同一時間死亡) 。意外的多線程結果和時間
但我看到在控制檯輸出第一個線程開始在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
我錯過了什麼?爲什麼第二個線程等待第一個線程喚醒,第三個線程只有在第二個線程死亡後才啓動?
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