Java 在循环上创建线程
我是线程新手,所以我想了解在一个循环中创建一组Java 在循环上创建线程,java,multithreading,Java,Multithreading,我是线程新手,所以我想了解在一个循环中创建一组线程时,幕后发生了什么,以及它的含义/更好的方法 下面是一个例子: for (Page page : book) { Thread t = new Thread(new Runnable() { public void run() { //http request to get page and put into concurrent data structure } });
线程时,幕后发生了什么,以及它的含义/更好的方法
下面是一个例子:
for (Page page : book) {
Thread t = new Thread(new Runnable() {
public void run() {
//http request to get page and put into concurrent data structure
}
});
t.start();
threads.add(t);
}
//wait for threads
正如您可能看到的,在我目前的特定用例中,我正在通过HTTP请求的对象进行分页。我知道这里不一定需要线程,相反,我可以发出异步请求,但是如何(通过解释)改进它。在您的示例中,您正在为书中的每个页面
对象创建并启动一个新线程。如果系统中的页面比内核多得多,则此选项不可用
到目前为止,直接创建和启动线程并跟踪它们也有点低级
更好的解决方案是使用ExecutorService
并创建一些线程,例如,接近系统上的内核数量(对于I/O绑定任务,您可能希望创建更多线程:您可以查看此答案下面的注释)
例如:
final ExecutorService e =
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
for (Page page : book) {
e.submit( new Runnable() {
//http request to get page and put into concurrent data structure}
}
然后,您将等待执行器服务
终止其作业
请注意,根据从中获取信息的服务器的不同,您可能需要故意添加延迟,以避免“重击”服务器太多
某些网站会告诉您查询它们的频率(例如,比特邮票比特币交换允许每秒查询一次),如果您不尊重延迟,则会禁止您的IP。其他人不会给你任何好处,如果他们检测到你的网速过快,他们会简单地禁止你的IP。“如果你的系统上的页面比内核多得多,这将是无效的。”-你知道线程可能大部分时间都会被网络绑定和阻塞吗?是的,但我想了解如何更好地使用线程(正如我在帖子中所说,我更愿意用异步请求解决这个特定问题,但这让我思考如何更有效地管理java中的线程)。@Martin James:当然,但如果OP的书中有5000页,那么创建5000个线程就没有多大意义了“因为它们可能会被网络绑定”。使用ExecutorService和大小接近内核数的固定线程池是“良好做法”。生成无数线程不是。对答案进行了一点编辑。我认为他的观点(我也同意)是,如果你想让N核cpu保持忙碌(即最大化吞吐量)您希望总线程数T足够大,从统计上讲,运行的线程数接近N。如果有大量网络绑定线程花费大量时间被阻止,则需要使T>>N。@JVMATL:当然可以,但这里OP讨论的是从“图书服务器”获取“页面”“。我想这是一个独特的服务器。这与编写一个网络爬虫不同,它可以并行地从完全无关的站点获取网页。但是,当然,OP可能想要进行实验,并确定T>N,如果它能提供更好的吞吐量。。。