Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何在groovy中使用多线程访问1000个端点?_Multithreading_Grails_Groovy_Threadpool_Executorservice - Fatal编程技术网

Multithreading 如何在groovy中使用多线程访问1000个端点?

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()

我需要点击端点1000次以上才能从网站获取一些数据。因此,我阅读了一些教程来使用多线程来实现它。但我每次只想在同一方法上使用13个线程

@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();