所以我有一个程序,我需要发送很多(如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