Как достичь 1000 конечных точек, используя многопоточность в Groovy? - PullRequest
0 голосов
/ 14 января 2019

У меня есть требование к конечным точкам более 1000 раз , чтобы получить некоторые данные с веб-сайта. Поэтому я прочитал несколько руководств, чтобы использовать Многопоточность для достижения этой цели. Но одновременно я хочу использовать только 13 потоков для того же метода .

Так что в основном я использую 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();

Мой класс Groovy с именем ScraperService - это , реализующий интерфейс Runnable .

@Override
        void run() {
            println("In run method...................")
            try {
                Thread.sleep(5000);
                someMethod()
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

Проблема:

Моя проблема в том, что мои ExecutorService.submit(obj) и ExecutorService.execute(obj) не вызывают мой метод run () интерфейса Runnable.

В Groovy / Grails:

Существует также плагин executor Плагин Executor в Grails , но я не нашел подходящего примера, как его использовать.

Ответы [ 3 ]

0 голосов
/ 17 января 2019

GPars отлично подходит для такого типа вещей.

Ваш 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
    }
}
0 голосов
/ 18 января 2019

Прежде всего, я думаю, что есть проблема в groovy service классе с аннотацией @Transnational, которая не позволяет вызвать метод run () интерфейса Runnable. Если вы удалите @Transnational, он вызовет метод run (). Это случилось и в моем случае. Но я не уверен, может быть какая-то другая причина. Вы можете напрямую использовать:

ExecutorService threadPool =  Executors.newFixedThreadPool(13)
threadPool.execute(new Runnable() {
                            @Override
                            void run() {
                                Thread.sleep(5000);
                                someMethod()
                            }
                        })

Extra (Как я читаю ваш вопрос)

Если вы используете несколько потоков в одном и том же методе, он может быть сложным, поскольку все потоки будут использовать одни и те же локальные переменные этого метода, что может привести к проблемам. Лучше использовать несколько потоков для разных разных работ.

Но если вы хотите использовать один и тот же метод для выполнения нескольких потоков, то в моем сценарии лучше использовать Executors.newSingleThreadExecutor().

ExecutorService threadPool = Executors.newSingleThreadExecutor();

newSingleThreadExecutor () вызывает один поток, поэтому, если вы хотите выполнить несколько задач в нем, он не создает несколько потоков. Вместо этого он ожидает завершения одной задачи, а затем запускает следующую задачу в том же потоке.

Скорость: newSingleThreadExecutor по сравнению с несколькими потоками будет медленным, но безопаснее в использовании.

0 голосов
/ 14 января 2019

threadPool.submit не выполняет задачу

используйте threadPool.execute(obj) или threadPool.submit(obj).get()

вместо threadPool.submit(obj)

Подробности смотрите в документации:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable)

пример:

import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


ExecutorService pool=Executors.newFixedThreadPool(3)

for(int i=0;i<7;i++){
    int x=i;
    Thread.sleep(444);
    pool.execute{
        println "start $x"
        Thread.sleep(3000+x*100);
        println "end   $x"
    }
}

println "done cycle"
pool.shutdown()                 //all tasks submitted
while (!pool.isTerminated()){}  //waitfor termination
println 'Finished all threads'
...