Josh Morrison
Josh Morrison

Reputation: 7636

How to multithread a computationally intensive code segment in Java?

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

Answers (5)

Ravindra babu
Ravindra babu

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

Brian Risk
Brian Risk

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

Mark Storer
Mark Storer

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

Sean Patrick Floyd
Sean Patrick Floyd

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

icyrock.com
icyrock.com

Reputation: 28608

Look at any Java multi-threading tutorial, either the official one:

or some of the others, e.g.:

Upvotes: 3

Related Questions