#потоки_данных #java #циклы
Помогите разобраться с тем, как можно распараллеливать циклы.. Вот допустим у меня есть некоторый метод, который должен вызываться с разными входными параметрами в цикле. Результат записывается в массив. Каждая итерация цикла независима от других. Как распараллелить этот процесс? И еще, как мне быть в такой ситуации: public class MainClass(){ public void main(){ Generator g = new Generator(); for (int i = 0; i < 10; i++){ ArrayListres = 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
Комментариев нет:
Отправить комментарий