2016-10-05 4 views
0

пытался выполнить параллельные операции с Gpars.Нити Gpars.withPool в конечном итоге прекращают выполнение после многократного повторения

Gpars.withPool(6) { 
    someList.eachParallel { 
    println "${Thread.currentThread}" 
    } 
} 

Первоначально кажется, работает

Thread[ForkJoinPool-1-worker-1,5,main] 
Thread[ForkJoinPool-1-worker-6,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-5,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-4,5,main] 
Thread[ForkJoinPool-1-worker-1,5,main] 
Thread[ForkJoinPool-1-worker-6,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 

Но после того, как итерация на некоторое время, некоторые из потоков прекращает выполнение.

Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 

До тех пор пока у нас не останется только один.

Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 
Thread[ForkJoinPool-1-worker-2,5,main] 

Любая идея, почему это происходит? Любое решение, чтобы сохранить все потоки активными?

В моем случае, возможно, стоит упомянуть, что мы выполняем итерацию около 50k-200k.

+0

Есть ли другие темы, которые закончили свою работу? сколько строк распечатывается? –

+0

Да, они есть. Я совершенно уверен, что они не зациклились на чем-то. Поскольку на моих тестах они просто печатаются. – froi

+0

Что касается количества раз, я считаю, что он может завершить количество итераций, предназначенных – froi

ответ

0

На всякий случай у других людей такая же проблема. В их документации написано:

Поскольку GParsPool использует пул Fork/Join (с кражей работы), потоки не могут применяться к задаче обработки ожидания, даже если они могут казаться бездействующими. С помощью алгоритма обработки работы рабочие потоки, которые не работают, могут украсть задачи из других потоков, которые все еще заняты.

Если вы используете GParsExecutorsPool, который не использует Fork/Join, вы получите поведение распределения потоков, которое вы наивно ожидаете.

Основываясь на этом, я предпочитаю вместо этого использовать GParsExecutorsPool. При этом все потоки выполняются последовательно до конца всего каждого параллельного процесса.

GParsExecutorsPool.withPool(6) { 
    someList.eachParallel { 
    println "${Thread.currentThread}" 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^