#потоки_данных #java #циклы
Помогите разобраться с тем, как можно распараллеливать циклы..
Вот допустим у меня есть некоторый метод, который должен вызываться с разными входными
параметрами в цикле. Результат записывается в массив.
Каждая итерация цикла независима от других. Как распараллелить этот процесс?
И еще, как мне быть в такой ситуации:
public class MainClass(){
public void main(){
Generator g = new Generator();
for (int i = 0; i < 10; i++){
ArrayList res = g.funcion(i); // здесь все должно выполняться последовательно
System.put.println(res.size());
}
}
}
public class Generator(){
public function(int i){
// Вот тут то и хотелось бы распараллелить выполнение метода function2
ArrayList res = new ArrayList();
res.addAll(function2(i));
res.addAll(function2(i*i));
}
public function2(int i){
// ...
}
}
Ответы
Ответ 1
Если каждая итерация цикла из main не зависит от других, то логичнее было бы запускать каждую итерацию в отдельном потоке (а не вызовы function2, как вы хотите). Тогда вам понадобится список результатов работы каждого потока и какой-нибудь пул потоков, отслеживающий, завершили ли они работу. После запуска всех потоков, основной поток будет засыпать, а когда все потоки отработают, пул его разбудит, он пройдётся по результатам, и выведет их на экран. Для хранения результатов работы потоков лучше использовать не простой List, а потокобезопасный. Такой можно получить либо при помощи Collections.synchronizedList(Listlist), либо при помощи ReentrantLock, либо заворачивая обращения к этому списку в synchronized-блок. В качестве пула потоков можно использовать ThreadPoolExecutor. В этой статье кратко описано, как им пользоваться. А ещё можно дождаться выхода Java 8, в которой всё это реализовано на уровне API. Ответ 2
Есть нечто вроде LinQ для Java - библиотека LambdaJ с помощью ее можно обращаться с коллекциями как некими сущностями не прибегая к циклу по их внутренностям. Не уверен, что на выходе будет параллельное выполнение - это уже зависит от компилятора. Но синтаксически будет довольно красиво как в SQL. Реальное распараллеливание можно сделать с помощью Thread'ов, но результат вам не понравится...Ответ 3
Создай класс, который будет реализовать интерфейс Runnable public class YourClass implements Runnable{ private int myInt; public YourClass(int _myInt){ myInt = _myInt; } @Override public void run(){ // Твой код } } А вместо res.addAll(function2(i*i)); Напиши Thread thread = new Thread(new YourClass(i)); thread.start(); Код из function2 перенеси в run()Ответ 4
как-то так: public abstract class ThreadHelper { public staticvoid exec(Callable ...callable) throws InterruptedException { // validate input if (null == callable || 0 == callable.length) { return; } List > tasks = Arrays.asList(callable); // special for @IronVbif int cores = Runtime.getRuntime().availableProcessors(); // execute thread group ExecutorService threadpool = Executors.newFixedThreadPool(cores*2); threadpool.invokeAll(tasks); threadpool.shutdown(); } @SuppressWarnings("unchecked") public static void main(String[] args) { final List
Комментариев нет:
Отправить комментарий