2010-05-05 153 views
7

我想打一個HTTP請求,然後獲得響應,勾勒這裏:Java BufferedReader readline阻塞?

URLConnection c = new URL("http://foo.com").openConnection(); 
c.setDoOutput(true); 

/* write an http request here using a new OutputStreamWriter(c.getOutputStream) */ 

BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream)); 
reader.readLine(); 

但我的問題是,如果我發送請求需要在收到響應之前很長一段時間,在通話時會發生什麼reader.readLine()以上?這個過程是否會繼續在CPU上運行/運行,或者它是否會從CPU中被取走,並在IO被讀取時被通知喚醒並再次運行?

如果它停留在CPU上,可以做些什麼來讓它下車並稍後通知?

+6

有沒有這些答覆足以解釋你的問題?如果是這樣,你應該將其中一個標記爲你接受的答案。如果沒有,只需編輯你的問題來說明什麼還不清楚。 – jasonmp85 2010-05-28 08:10:38

回答

-3

一個好的操作系統會有一個調度程序,它將進程置於阻塞或類似的狀態,並且任何任務開關都不會切換到被阻塞的進程。

例如, 窗口中的空閒進程是當沒有進程準備好運行(睡眠,阻塞等)時運行的進程。

21

其他人說的是正確的。 Java中的Java「舊I/O」庫包含阻塞調用。但他們並不忙等。它們在I/O上阻塞,並且內核將重新調度它們,再次提供I/O。

我並不完全確定,所以我嘗試了自己。以下示例類別:

import java.io.*; 

public class Test { 

    public static void main(String[] args) throws IOException { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 

    String line = reader.readLine(); 
    System.out.println(line); 
    } 
} 

然後在命令行上編譯它。然後運行它,但不要輸入任何內容。程序在輸入字符之前應該被阻塞,直到你輸入一個字符,它纔會超過readline。 ps應該能夠告訴我們關於這個過程的更多細節。使用a標誌,以避免ps獲得更詳細的信息:

[email protected]<computer-name>] ps a 
    PID TT STAT  TIME COMMAND 
3846 s000 S  0:00.16 -zsh 
3992 s000 S+  0:00.40 /usr/bin/java Test 

爲PS的手冊頁說:

狀態狀態由字符 序列表中給出,例如, ``RWNA'。第一個字符 表示 過程的運行狀態:

  • 標記一個過程,是空閒(昏睡長於約 20秒)。
  • R標記可運行的進程。
  • S標記睡眠時間少於約20秒的進程。

而且因爲我剛開始的過程中,小號是有道理的。該進程正在休眠,正在等待OS調度。事實上,如果你檢查top,你會注意到這個過程正在佔用0%的CPU。

所以不要擔心這個調用的性能,沒有忙於等待或輪詢進行:系統正在爲您處理I/O事件,並將智能地處理您的過程。