有没有一种简单的方法可以并行化Java中的foreach循环?

编程入门 行业动态 更新时间:2024-10-25 20:24:48
本文介绍了有没有一种简单的方法可以并行化Java中的foreach循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

是否有一种简单的方法可以使用某些库内容并行化Java 8中的foreach循环?

Is there a easy way to parallelise a foreach loop in java 8 using some library stuff?

void someFunction(SomeType stuff, SomeType andStuff) { for (Object object : lotsOfObjects) object.doSomethingThatCanBeDoneInParallel(stuff, andStuff); }

多线程是一个痛苦且耗时的过程,所以我想知道是否存在使用某些库完成上述操作的更简单方法.

Multithreading is kinda painful and time consuming so i wonder if there is a simpler way to do the above using some library.

谢谢.

于2018年6月3日编辑

edited in 3/06/2018

ExecutorServices确实非常方便,我不能使用shutdown()来等待,因为我每帧都运行一次东西,并且每帧创建一个新的ExecutorServices太昂贵了.

ExecutorServices is very handy indeed, I can't use shutdown() to wait because I run the thing every frame and create a new ExecutorServices every frame would be too expensive.

我最终写了一个类来并行化一个fori循环,我以为我可以和其他像我这样的新手分享它.

I ended up writing a class to parallelize a fori loop and I thought I share it with other newbies like me.

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; public class ParallelForI { public ParallelForI(int numberOfThread) { NUMBER_OF_THREAD = numberOfThread; executorService = Executors.newFixedThreadPool(NUMBER_OF_THREAD); finished = new AtomicBoolean[NUMBER_OF_THREAD]; for (int i = 0; i < finished.length; i++) finished[i] = new AtomicBoolean(true); // true is better for waitForLastRun before any run. } private ExecutorService executorService; private final int NUMBER_OF_THREAD; private AtomicBoolean[] finished; public void waitForLastRun() { synchronized (this) { /* synchronized outside the loop so other thread can't notify when it's not waiting. */ for (int i = 0; i < NUMBER_OF_THREAD; i++) { if (!finished[i].get()) { i = -1; try { this.wait(); // } catch (InterruptedException e) { // do nothing and move one. } } } } } public void run(FunctionForI functionForI, final int MAX_I) { for (AtomicBoolean finished : finished) finished.set(false); // just started for (int i = 0; i < NUMBER_OF_THREAD; i++) { final int threadNumber = i; executorService.submit(new Runnable() { @Override // use lambda if you have java 8 or above public void run() { int iInitial = threadNumber * MAX_I / NUMBER_OF_THREAD; int iSmallerThan; if (threadNumber == NUMBER_OF_THREAD - 1) // last thread iSmallerThan = MAX_I; else iSmallerThan = (threadNumber + 1) * MAX_I / NUMBER_OF_THREAD; for (int i1 = iInitial; i1 < iSmallerThan; i1++) { functionForI.run(i1); } finished[threadNumber].set(true); synchronized (this) { this.notify(); } } }); } } public interface FunctionForI { void run(int i); } }

这是使用它的方式:

void someFunction(final SomeType stuff, final SomeType andStuff) { ParallelForI parallelForI = new parallelForI(numberOfThread); // swap numberOfThread with a suitable int parallelForI.run(new ParallelForI.FunctionForI() { @Override // use lambda if you have java 8 or above public void run(int i) { lotsOfObjects[i].doSomethingThatCanBeDoneInParallel(stuff, andStuff); // don't have to be array. } }, lotsOfObjects.length); // again, don't have to be array parallellForI.waitForLastRun(); // put this where ever you want // You can even put this before parallelForI.run(). // Although it doesn't make sense to do that... // Unlike shutdown() waitForLastRun() will not cause parallelForI to reject future task. }

推荐答案

解决方案可能是在Thread中启动每个任务,如下所示:

A solution could be to launch every task in a Thread as follows:

new Thread(() -> object.doSomethingThatCanBeDoneInParallel(stuff, andStuff)).start();

但这不是一个相关的解决方案,因为创建线程的成本很高,因此有一些机制和工具可以帮助您:Executors类用于构建某些pools.

but this is not a relevant solution as Thread creation is costly, so there are mechanisms and tools to help you: the Executors class to build some pools.

一旦有了将要管理该实例的实例,便会为其提供任务,这些任务将根据您选择的线程数并行运行:

Once you have the instance that will manage this, you provide it with tasks, which will run in parallel, on the number of threads you choose:

void someFunction(SomeType stuff, SomeType andStuff) { ExecutorService exe = Executors.newFixedThreadPool(4); // 4 can be changed of course for (Object object : lotsOfObjects) { exe.submit(() -> object.doSomethingThatCanBeDoneInParallel(stuff, andStuff)); } // Following lines are optional, depending if you need to wait until all tasks are finished or not exe.shutdown(); try { exe.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { e.printStackTrace(); } }

更多推荐

有没有一种简单的方法可以并行化Java中的foreach循环?

本文发布于:2023-05-28 06:51:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/315059.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:词库加载错误:Could not find file &#039;D:\淘小白 高铁采集器win10\Configuration\Dict_Sto

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!