我有一个类需要提供快速分类服务。例如,我想编写类似“classify(”Ac Kd Kh 3c 3s“)”的代码,它很快返回TWO_PAIR。 (这不是应用程序,但你得到了jist)静态initalizer块中的多线程代码产生死锁
因为我需要快速的分类我想预先计算,然后存储一个查找表,列出所有可能的输入的分类输出。为了时间的利益,我希望将这个预计算并行化。但是,试图从第二个线程使用“classifySlowly”会造成死锁。
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;
}
}
所以我的问题是:有没有一种方法来预先计算静态initalizer块内的并行查找表?
唯一的(差)替代我看到的是切换从:
preComputedClassLookUpTable = constructLookUpTableInParallel();
要:
preComputeClassLookUpTable = loadLookUpTableFromFile();
if(preComputedClassLookUpTable == null) {
System.out.println("WARNING: Construction incomplete, Must call computeAndSaveLookUpTableFile();}
}
我想这将是太多,但这里是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
}
////////底部原文问题结束///////////
解决方案的工作原理有点干净,就是将classifySlowly(Object classifyMe)和classify(Object classifyMe)方法分成两个不同的类。
这将允许包含“public static CLASS classifySlowly(Object classifyMe)”的(第一个)类在包含“public static CLASS classifyQuickly(Object classifyMe)”的(second)类需要的时候完全加载使用classifySlowly方法。现在,第二个静态初始化块不需要任何自己的静态方法,它可以完全并行化。
这是相当困难的调试多线程代码时,你不要张贴多线程代码。什么是'constructLookUpTableInParallel'在做什么? –
你怎么知道它的僵局?为什么'loadLookUpTableFromFile'糟糕的选择?预先计算并存储在文件中可能是一个好主意,以便更快地初始化 –
@JohnB - 它隐藏了复杂性。如果constructLookUpTableInParallel没有启动新的线程,程序会正常工作。但是,如果您必须知道,它会创建一组Runnables来执行每个分类任务,然后将这些Runnables提交给ExecutorService – Ivan