所以我有一個程序,我需要發送很多(如10,000+)GET請求到一個URL,我需要它儘可能快。當我第一次創建程序時,我只是把連接放到for循環中,但是它非常慢,因爲在繼續之前它必須等待每個連接完成。我想讓它更快,所以我嘗試使用線程,它使它更快,但我仍然不滿意。瞭解線程+異步
我猜這是正確的方法,並使其真正快速使用異步連接並連接到所有的URL。這是正確的方法嗎?
此外,我一直在嘗試理解線程和它們是如何工作的,但我似乎無法得到它。我所在的電腦有一個英特爾酷睿i7-3610QM四核處理器。根據英特爾網站對這款處理器的規格說明,它有8個線程。這是否意味着我可以在Java應用程序中創建8個線程,並且它們都將同時運行?如果超過8,那麼速度不會提高?
該數字代表「性能」選項卡下任務管理器中「線程」旁邊的數字是什麼?目前,我的任務管理器顯示「線程」超過1,000。爲什麼這個數字,如果這是我所有的處理器支持,它甚至會超過8? 我還注意到,當我用500個線程作爲測試來測試我的程序時,任務管理器中的數字增加了500,但它具有相同的速度,如果我將它設置爲使用8個線程來代替。所以如果數量是根據我在Java應用程序中使用的線程數量增加的,那麼爲什麼速度是相同的呢?
此外,我已經嘗試使用Java中的線程做一個小測試,但輸出對我來說沒有意義。 這裏是我的測試類:
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
private static int numThreads = 3;
private static int numLoops = 100000;
private static SimpleDateFormat dateFormat = new SimpleDateFormat("[hh:mm:ss] ");
public static void main(String[] args) throws Exception {
for (int i=1; i<=numThreads; i++) {
final int threadNum = i;
new Thread(new Runnable() {
public void run() {
System.out.println(dateFormat.format(new Date()) + "Start of thread: " + threadNum);
for (int i=0; i<numLoops; i++)
for (int j=0; j<numLoops; j++);
System.out.println(dateFormat.format(new Date()) + "End of thread: " + threadNum);
}
}).start();
Thread.sleep(2000);
}
}
}
這將產生一個輸出,如:
[09:48:51] Start of thread: 1
[09:48:53] Start of thread: 2
[09:48:55] Start of thread: 3
[09:48:55] End of thread: 3
[09:48:56] End of thread: 1
[09:48:58] End of thread: 2
爲什麼第三個線程開始和結束的時候了,而第一和第二採取每次5秒了嗎?如果我添加更多的3個線程,同樣的事情發生在2以上的所有線程。
對不起,如果這是一個長時間的閱讀,我有很多問題。 在此先感謝。
感謝您的回覆。 編輯... – user1203585
啊,我不能編輯評論真的... 5分鐘的限制...... 「是否有所有線程共享的任何對象?這是否對象有任何synchronized方法?」 我所有的線程都在做同樣的事情: 它實例化一個URL對象,並打開與代理的連接。它設置URLConnection連接和讀取超時。然後它使用BufferedReader和InputStreamReader從URLConnection讀取。最後,它將一個單詞寫入一個文本文件。 這就是每個線程正在做和運行這些線程500似乎並沒有加快步伐:/ – user1203585
我做了一些周圍挖掘。我懷疑Java的底層連接池的大小是有限的。有一個名爲http.maxConnections [見這裏]一個網絡屬性(http://docs.oracle.com/javase/1.4.2/docs/guide/net/properties.html)。默認值爲5。這意味着你有它們都使用相同的5個底層套接字(共享資源),並且您之後打開將阻止任何連接超過5個連接打開之後。再次,您可以使用JVisualVM來確認這一點。 – Pace