Flopn
Flopn

Reputation: 195

Run a dynamic number of threads with value return in Java

So basically I'm trying to implement a Genetic Algorithm, but the part that worries me is optimization. I'm trying to make a Class that checks the fitness of each node, however I'd like to run simultaneous checks because the data won't be altered in the checking process, and is the same for each thread. What I've come up to is this:

// check the gene for overlaps in room reservation
    for (int i=0;i<nrRooms;i++){
    FitnessThread thread = new FitnessThread(chromosome);
    }

With the thread's run function executing the checking code and filling an integer with the number of violations, to shorten it up:

for(int j=0; j<individualLength; j++){
                if(chromosome.getGene((offset*individualLength)+j) * 
                    chromosome.getGene((offsetNext*individualLength)+j) != 0){
                    violations++;
                }
            }

My question is, how can I collect the violations from each individual thread without ending up in a linear process. Can I just declare an array of threads and then start them at the same time, and collect from each individually once they've executed? Or is there some other method?

Thanks in advance

Upvotes: 0

Views: 756

Answers (2)

Peter Lawrey
Peter Lawrey

Reputation: 533660

In Java 8 you can do

public class A {
    public static void main(String[] args) {
        List<Chromosome> chromosomes = new ArrayList<>();
        List<Pair<Double, Chromosome>> sortedByFitness 
                = chromosomes.parallelStream()
                .map(c -> Pair.of(c.finess(), c))
                .sorted(Comparator.comparing(p -> p.l).reversed())
                .limit(100) // best 100 values.
                .collect(Collectors.toList());
    }
}

class Pair<L, R>{
    L l;
    R r;

    public Pair(L l, R r) {
        this.l = l;
        this.r = r;
    }

    public static <L, R> Pair<L, R> of(L l, R r) {
        return new Pair<>(l, r);
    }
}

Upvotes: 0

Kayaman
Kayaman

Reputation: 73568

You could create Callables and submit them to an executor pool, then use Future.get(); to retrieve their results.

ExecutorService executor = Executors.newFixedThreadPool(4); // or another kind of executor
List<Future<Foo>> futures = new ArrayList<>();
for(int i = 0;i < nrRooms; i++) {
    futures.add(executor.submit(new FitnessCallable(chromosome)));
}
...
// Time to check the results
for(Future<Foo> f : futures) {
    Foo result = f.get();  // Block and get the result
}

Upvotes: 2

Related Questions