Multithreading 如何在groovy中使用多线程访问1000个端点?
我需要点击端点1000次以上才能从网站获取一些数据。因此,我阅读了一些教程来使用多线程来实现它。但我每次只想在同一方法上使用13个线程Multithreading 如何在groovy中使用多线程访问1000个端点?,multithreading,grails,groovy,threadpool,executorservice,Multithreading,Grails,Groovy,Threadpool,Executorservice,我需要点击端点1000次以上才能从网站获取一些数据。因此,我阅读了一些教程来使用多线程来实现它。但我每次只想在同一方法上使用13个线程 @Override void run() { println("In run method...................") try { Thread.sleep(5000); someMethod()
@Override
void run() {
println("In run method...................")
try {
Thread.sleep(5000);
someMethod()
} catch (InterruptedException e) {
e.printStackTrace();
}
}
因此,基本上我使用ExecutorService一次运行13个线程:
ExecutorService threadPool = Executors.newFixedThreadPool(13);
for (int itLocation = 0; itLocation < locationList.size(); itLocation++) {
//some code like
ScraperService obj = new ScraperService(threadName,url)
threadPool.submit(obj);
}
threadPool.shutdown();
问题:
我的问题是我的ExecutorService.submit(obj)
和ExecutorService.execute(obj)
没有调用Runnable接口的My run()方法
在Groovy/Grails中:
还有一个executor插件,但我没有找到任何合适的示例来使用它。
threadPool.submit
不执行任务
使用threadPool.execute(obj)
或threadPool.submit(obj.get()
而不是threadPool.submit(obj)
有关详细信息,请查看文档:
例如:
导入java.util.concurrent.ExecutorService
导入java.util.concurrent.Executors
ExecutorService池=Executors.newFixedThreadPool(3)
对于(inti=0;iGPars)来说,这种类型的东西非常适合
您的ScraperService可以像下面这样负责处理被刮取的数据,或者也可以获取它,不管怎样
import groovyx.gpars.GParsPool
def theEndpoint = 'http://www.bbc.co.uk'
def scraperService
GParsPool.withPool( 13 ) {
(1..1000).eachParallel {
scraperService.scrape theEndpoint.toURL().text
}
}
首先,我认为带有@Transnational
注释的groovy service类存在问题,该类不允许调用Runnable接口的run()方法。如果删除@Transnational
,它将调用run()方法。在我的案例中也发生过。但我不确定,可能还有其他原因。您可以直接使用:
ExecutorService threadPool = Executors.newFixedThreadPool(13)
threadPool.execute(new Runnable() {
@Override
void run() {
Thread.sleep(5000);
someMethod()
}
})
额外(当我读到你的问题时)
如果在同一个方法上使用多个线程,那么可能会很复杂,因为所有线程都将使用该方法的相同局部变量,这可能会出现问题。最好为不同的工作使用多个线程
但是,如果您想使用相同的方法执行多个线程,那么在我的场景中,最好使用Executors.newSingleThreadExecutor()
newSingleThreadExecutor()调用单个线程,因此如果要在其上执行多个任务,它不会创建多个线程。相反,它会等待一个任务完成,然后在同一线程上启动下一个任务
速度:与多线程相比,newSingleThreadExecutor速度较慢,但使用起来更安全。您为什么不使用threadPool.invokeAll(任务);
?但在您的情况下,我想您必须调用threadPool.awaitTermination()
我现在不讨论threadPool.invokeAll(任务);因此,如果我想执行1000个线程,那么对于每个线程,我应该使用hreadPool.submit(obj).get()。实际上也使用threadPool.execute(obj)方法,我的调用不会覆盖run()方法。如果使用execute(),您将无法判断您的runnable是否已运行。使用submit(),您应该保存所有返回的期货,然后在它们上循环检查get()。注意InterruptedException。Guava's Futures.getUnchecked()在这里可以起到很大的帮助。
ExecutorService threadPool = Executors.newSingleThreadExecutor();