views:

396

answers:

4

Hey folks,

I am writing an optimazation algorithm which creates about 100 threads. Currently, I start them all at one time (for-loop) and after that I tell every thread that it should join().

My problem is now that each thread uses to much memory so the heap space exception won't take long. I want some kind of scheduling but don't know how to implement it.

I have something like this in mind: start 10 threads and every time one of these finishes start a new one. So that there are allways running 10 threads at a time until no thread is left.

Has someone an idea or knows how to realize something like this?

Thank you very much and regards from Cologne

Marco

+18  A: 

Use a ThreadPoolExecutor with an appropriate maximum pool size.

Michael Borgwardt
+1  A: 

Instead of starting a new Thread to do a new task, you are much better off to:

  • have a queue of tasks to execute (instead of threads to run)
  • use a smaller pool of threads (as mentionned by Michael) to process these tasks.

The difference in speed and memory is huge, because you don't have to start and stop a thread for each task.

The package java.util.concurrent explains everything about this. A book would be easier to read though :-(

KLE
+3  A: 

Hiya,

Here's an example to get you started. First, what you'll need to import:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

And then what you need to put inside your method:

    ExecutorService pool = Executors.newFixedThreadPool(10);
    for(final Task task: tasks) { 
        pool.execute(new Runnable() {
            @Override
            public void run() {
                task.execute();
            }
        });
    }
    pool.shutdown();
    while(!pool.awaitTermination(1, TimeUnit.SECONDS)) {
        System.out.println("Waiting for tasks to shutdown");
    }

Some notes about the above:

  • You'll need to implement your own Task class that actually implements your algorithm
  • The task class doesn't have to just have an execute method (in fact, if it has that signature, you could just get your task to implement Runnable and avoid the anonymous inner class)
  • You'll need to make sure that everything that you use is properly synchronised. The classes in java.util.concurrent.atomic are quite good if you have shared state you need to update (e.g. if you want to have a counter for how many tasks you've processed).
  • You typically only want as many threads executing as there are cores / cpus on your machine. Often performance often goes up when numbers of threads goes down. Normally you only use more threads if your tasks spend a lot of time blocked.
jamie mccrindle
+1  A: 

Consider the number of cores in the machine you will be using. Performance will be best if the number of threads you normally have running equals the number of cores. As KLE says, use a thread pool.

rleir
I currently run 2 a time cause its a Core2Duo from Intel. Performance looks good...
Marco