2013-09-29 47 views
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 

回答

0

據我所看到的,沒有什麼你的代碼錯誤。然而,同樣的事情發生在我身上,所以我試着自己運行它,同時使用tcpdump監控網絡流量,看起來它只是瀏覽器玩弄技巧,而不是你的代碼。

我正在使用Chromium,它只是不發送第二個請求,直到第一個請求完成,甚至直到第三次都沒有連接。我猜測它試圖對服務器保持友善,不要超載它,或者其他什麼東西。