java foreach并行,有没有一种简单的方法可以并行化Java中的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.

thanks.

edited in 3/06/2018

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.

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);

}

}

And this is the way to use it:

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.

}

解决方案

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

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

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();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值