I need some help retrieving results from executors. The place where I create the workers:
public static void method()
{
double bestProb = 0;
double best p1 = 10000;
double best p2 = 10000;
executor = Executors.newFixedThreadPool(5);
List<Future<Double>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
double p1 = Math.pow(2, i);
for (int j = 5; j < 15; j++) {
double p2 = Math.pow(2, j);
Callable<Double> worker = new ProbabilityCalculator(p1, p2,);
futures.add(executor.submit(worker));
}
}
for (Future<Double> future : futures) {
double prob = future.get();
prob /= 100;
if (prob > bestProb) {
bestProb = prob;
bestp1 = p1;
bestp2 = p2;
}
}
System.out.println("Best prob: " + bestProb + ", for: " + bestp1 + ", " + bestp2);
}
The ProbabilityCalculator
class which I want to return a probability that I have to process back in the method
with the parameters p1
and p2
that lead to this probability.
public class ProbabilityCalculator implements Callable<Double> {
private double p1;
private double p2;
private double probability;
private void processCommand() {
// perform operations
// here I compute the probability each time
}
public double returnProbability() {
return this.probability;
}
@Override
public void call() {
processCommand();
}
}
(This answer was provided when the question was at revision 1. The OP is editing the question in response to the answer, which makes the answer make less sense - rather than me try to keep up with the edits, please refer to revision 1 to see what this was all responding to...)
If you use Callable
instead of Runnable
, you can use the future returned by the executor to get the return value. If you just want the probabilities, you could use a Callable<Double>
like this:
List<Future<Double>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
double p1 = Math.pow(2, i);
for (int j = 5; j < 15; j++) {
double p2 = Math.pow(2, j);
Callable<Double> worker = new ProbabilityCalculator(p1, p2);
futures.add(executor.submit(worker));
}
}
// Do whatever else you want to here...
// Now wait for the results and handle them appropriately.
// Note the exceptions that can be thrown...
for (Future<Double> future : futures) {
double value = future.get();
...
}
The important thing here is that a Runnable
doesn't return a value, whereas a Callable
does.
As it sounds like you need the p1
and p2
values as well, you should probably encapsulate that in a result type, so you'd implement Callable<ProbabilityResult>
, e.g.
public class ProbabilityCalculator implements Callable<ProbabilityResult> {
private final double p1, p2;
public ProbabilityCalculator(double p1, double p2) {
this.p1 = p1;
this.p2 = p2;
}
public ProbabilityResult call() {
double probabilty = ...;
return new ProbabilityResult(p1, p2, probability);
}
}
(Where ProbabilityResult
would just be a simple data transfer class, effectively - you could just use a double[]
with three values, but that would be fairly unpleasant...)
Now you can use:
double bestProbability = -1;
double bestP1 = 0, bestP2 = 0;
for (Future<ProbabilityResult> future : futures) {
ProbabilityResult result = future.get();
if (result.getProbability() > bestProbability) {
bestProbability = result.getProbability();
bestP1 = result.getP1();
bestP2 = result.getP2();
}
}
Note that I've changed WorkerThread
to ProbabilityCalculator
- you should not be creating an instance of a subclass of Thread
here; the point is for the executor to handle the actual threading; you just provide it the tasks to execute. If your WorkerThread
class doesn't actually extend Thread
, you should rename it to something less misleading.
See more on this question at Stackoverflow