2014-02-24 63 views
0

我正在使用ARIN休息whois服務來查找組織的IP地址列表。由於列表非常長(下面的列表非常小),我選擇使用線程來實現更快的性能。線程中出現奇怪的http超時錯誤

public class SimpleThreadPool { 

    public final static String[] ips = { 
     "192.150.16.64","192.243.232.36","208.77.139.8","63.140.35.160", 
     "63.140.35.161","63.140.35.162","63.140.59.142","63.140.61.200", 
     "66.235.132.238","66.235.137.133","66.235.138.18","66.235.138.192", 
     "66.235.138.195","66.235.139.152","66.235.139.172","66.235.139.204", 
     "66.235.139.205","66.235.139.206","66.235.139.227","66.235.141.144", 
     "66.235.141.145","66.235.141.146","66.235.141.16","66.235.142.20", 
     "66.235.142.24","66.235.141.145","184.106.60.35","207.171.162.26", 
     "207.171.162.75","207.171.162.95","207.171.185.201","207.171.187.117", 
     "207.171.187.118","207.171.189.80","207.171.189.81","216.137.37.108", 
     "216.137.37.122","216.137.37.128","216.137.37.138","216.137.37.140", 
     "216.137.37.178","216.137.37.183","216.137.37.198","216.137.37.225", 
     "216.137.37.235","216.137.37.37","216.137.37.52","216.137.37.57", 
     "216.137.37.6","216.137.37.84" 
    }; 

    public static void main(String[] args) throws InterruptedException { 
     ExecutorService executor = Executors.newFixedThreadPool(4); 

     for (int i = 0; i < ips.length; i++) { 
      Runnable worker = new WorkerThread(ips[i]); 
      executor.execute(worker); 
     } 

     executor.shutdown(); 

     while (!executor.isTerminated()) {} 

     System.out.println("All threads finished."); 
    } 
} 

而這裏的WorkerThread:

public class WorkerThread implements Runnable { 

    private String workingIP; 

    public WorkerThread(String workingIP) { 
     this.workingIP = workingIP; 
    } 


    @Override 
    public void run() { 
     try { 
      URL url = new URL("http://whois.arin.net/rest/ip/" + workingIP); 

      InputStream inputStream = null; 
      HttpURLConnection con = (HttpURLConnection)(url.openConnection()); 
      con.connect(); 
      inputStream = con.getInputStream(); 

      BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 

      String line = null; 
      while((line=br.readLine()) != null) 
      { 
       if (line.contains("<td>Organization</td><td>")) { 
        String companyName = line.replace("<td>Organization</td><td>", "").trim(); 
        System.out.println(workingIP + " maps to: " + companyName); 
        break; 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

對我的工作機(W /一個i5-2400,4GB內存,32位的Win7),該代碼工作正常,一路下降到大約第45 +陣列中的IP地址。然後我得到java.net.ConnectException錯誤拋出剩餘查找:

... 
216.137.37.57 maps to: Amazon.com, Inc. 
216.137.37.6 maps to: Amazon.com, Inc. 
java.net.ConnectException: Connection timed out: connect 
     at java.net.PlainSocketImpl.socketConnect(Native Method) 
     at java.net.PlainSocketImpl.doConnect(Unknown Source) 
     at java.net.PlainSocketImpl.connectToAddress(Unknown Source) 
     at java.net.PlainSocketImpl.connect(Unknown Source) 
     at java.net.SocksSocketImpl.connect(Unknown Source) 
     at java.net.Socket.connect(Unknown Source) 
     at java.net.Socket.connect(Unknown Source) 
     at sun.net.NetworkClient.doConnect(Unknown Source) 
     at sun.net.www.http.HttpClient.openServer(Unknown Source) 
     at sun.net.www.http.HttpClient.openServer(Unknown Source) 
     at sun.net.www.http.HttpClient.<init>(Unknown Source) 
     at sun.net.www.http.HttpClient.New(Unknown Source) 
     at sun.net.www.http.HttpClient.New(Unknown Source) 
     at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source) 
     at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) 
     at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) 

如果我改變執行程序的線程池大小爲1,則一切正常,沒有錯誤拋出,但很明顯的查詢需要更長的時間。

真是個奇怪的事情是,如果我跑我的2011酷睿i7的Mac相同的代碼,沒有任何錯誤拋出。當然,這兩者在不同的網絡上(我的工作機器使用我工作的網絡,而我的Mac無線連接到智能手機)。

任何想法是怎麼回事,和我能做些什麼來解決這個問題?

回答

0

您需要編寫合理的錯誤處理代碼。這真的很簡單。如果連接超時,你想怎麼做?如果您在慢速網絡上同時進行大量連接,其中一些可能會超時。

+0

我同意上面的catch語句並不理想。它只是爲了說明問題的本質(在完成的應用程序中錯誤處理將更加健壯)。雖然問題不是一個緩慢的網絡(我的工作連接是@ 25 Mb/s以下)。我可以捕獲這些異常,也許嘗試重試請求,但是我最好還是堅持單線程解決方案,從不拋出這個錯誤,因爲對於更長的列表來說,這可能會更快。 – benjammin

+0

@Brutalisk多線程解決方案對於更長的列表來說將會快得多,只要你開始準確地調整自己,並在開始出現連接錯誤時退出。 –

相關問題