Reputation: 7636
I hava a java program, a section of it is compute intensive, like this
for i = 1 :512
COMPUTE INTENSIVE SECTION
end
I want to split it into multithread, make it faster when running.
COMPUTE INTENSIVE SECTION is not sequential-wise. It means running i=1 first or i=5 fist are the same...
Can anybody give me a grand guide about this. How to do it? Thanks indeed! Happy Thanksgiving!
Upvotes: 5
Views: 1111
Reputation: 38910
If you can split your intensive action to recursive smaller sub tasks, ForkJoinPool is ideal for you.
If your server is running with 8 core CPU
, you can set the pool size as 8
ForkJoinPool forkJoinPool = new ForkJoinPool(8);
OR
you can use Executor Service FixedThreadPool
by moving compute intensive task to Callable
as below
ExecutorService executorService = Executors.newFixedThreadPool(8);
Future future = executorService.submit(new Runnable() {
public void run() {
System.out.println("Your compute intensive task");
}
});
future.get(); //returns null if the task has finished correctly.
There is one advantage with ForkJoinPool
. Idle threads will steal jobs from busy threads from blokcingQueue where your Runnable/Callable
tasks have been submitted.
Java 8 added one more new API in Executors
: newWorkStealingPool
If you need to wait for completion of all tasks, use can use invokeAll()
on ExecutorService
.
Have a look at this article by Benjamin
for advanced concurrent APIs using Java 8
Upvotes: 0
Reputation: 1449
Similar to Sean Patrick Floyd's answer, but a bit less verbose with a lambda expression:
ExecutorService es = Executors.newCachedThreadPool();
for(int i = 0; i < 512; i++){
es.execute(() -> {
// code goes here
});
}
Upvotes: 0
Reputation: 15868
Sounds like a thread pool would be good. Basically, you whip up a collection of N different threads, then request them in a loop. The request blocks until a thread is available.
ThreadPool pool = Executors.newFixedThreadPool(10); // 10 threads in the pool
ArrayList<Callable> collectionOfCallables = new ArrayList<Callable>( );
for (...) {
Callable callable = new Callable<Foo>() { public Foo call() { COMPUTE INTENSIVE SECTION } }
collectionOfCallables.add(callable);
}
ArrayList<Future<Foo>> results = pool.invokeAll( collectionOfCallables );
pool.awaitTermination(5, TimeUnit.MINUTES ); // blocks till everything is done or 5 minutes have passed.
With the Future's you really don't need to await termination. get()ing the result from a future will block until the corresponding thread is done (or canceled).
Upvotes: 3
Reputation: 298908
You should read the Concurrency Trail of the Java Tutorial. Especially Executors and Thread Pools should be relevant for you.
Basically, you create a thread pool (which is an Executor
) through one of the factory methods in the Executors
class and submit Runnable
instances to it:
for(int i = 0; i < 512; i++){
executor.execute(new Runnable(){public void run(){
// your heavy code goes here
}});
}
Upvotes: 5
Reputation: 28608
Look at any Java multi-threading tutorial, either the official one:
or some of the others, e.g.:
Upvotes: 3