I have a class that needs to provide a fast classification service. For example, I want to write code like “classify(“Ac Kd Kh 3c 3s”)” that quickly returns TWO_PAIR. (This isn’t the application but you get the jist)
Because I need the classification to be quick I want to precompute, and then store, a look-up table that lists the classification output for all possible inputs. In the interest of time I want to parallelize this precomputation. HOWEVER, attempting to use “classifySlowly” from a 2nd thread creates a deadlock.
public class Classifcation Service {
enum CLASS {TYPE_A, TYPE_B, ...};
static CLASS[] preComputedClassLookUpTable;
static {
preComputedClassLookUpTable = constructLookUpTableInParallel();
}
//Note: using this method from with constructLookUpTableInParallel causes deadlock
private static CLASS classifySlowly(Object classifyMe) {
//do time intensive work to classify the input
// -- uses no other methods from this class
return classification;
}
public static CLASS classify(Object classifyMe) {
//use the lookup table to do a quick classification
return classification;
}
}
So my question is: Is there a way to precompute this lookup table IN PARALLEL from within the static initalizer block?
The only (poor) alternative I see is to switch from:
preComputedClassLookUpTable = constructLookUpTableInParallel();
To:
preComputeClassLookUpTable = loadLookUpTableFromFile();
if(preComputedClassLookUpTable == null) {
System.out.println("WARNING: Construction incomplete, Must call computeAndSaveLookUpTableFile();}
}
I thought this would be too much but here is the implementation of constructLookUpTableInParallel
private static CLASS[] constructLookUpTableInParallel() {
//build a collection of Runnables by iterating over all possible input Objects
//wrap each possible input in an anonymous Runnable that calls classifySlowly.
//submit the collection of Runnables to a new ExecutorService
//process runnables...
//shutdown executor service
}
////////END OF POORLY WORDED ORIGINAL QUESTION ///////////
The solution that works somewhat cleanly is splitting the classifySlowly(Object classifyMe) and classify(Object classifyMe) methods into two different classes.
This will allow the (first) class that contains “public static CLASS classifySlowly(Object classifyMe)” to be fully loaded by the time the (second) class that contains “public static CLASS classifyQuickly(Object classifyMe)” needs to use the classifySlowly method. Now, that the 2nd static inialization block don’t require any of its own static methods it can be fully parallelized.
“So my question is: Is there a way to precompute this lookup table IN PARALLEL from within the static initalizer block?”
Yes, it’s practically certain there is a way. Just new the array and launch a Runnable for each array element. Give each Runnable reference to the array, and index it is computing, then have it do the computing without locking, then lock when assigning result to the array element.
Note/disclaimer: this answer is based on the rather incomplete information given in the question…