静态初始化程序块中的多线程代码会产生死锁

时间:2012-10-23 15:20:33

标签: java multithreading static

我有一个类需要提供快速分类服务。例如,我想编写像“classify(”Ac Kd Kh 3c 3s“)这样的代码,它可以快速返回TWO_PAIR。 (这不是应用程序,但你得到了这个小说)

因为我需要快速分类,所以我想预先计算,然后存储一个查找表,列出所有可能输入的分类输出。为了时间的缘故,我想要并行化这个预计算。但是,尝试从第二个线程使用“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块中预先计算这个查询表IN PARALLEL?

我看到的唯一(差)替代方案是切换:

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)”的(第二个)类需要使用时完全加载classifySlowly方法。现在,第二个静态inialization块不需要任何自己的静态方法,它可以完全并行化。

1 个答案:

答案 0 :(得分:0)

“所以我的问题是:有没有办法从静态initalizer块中预先计算这个查询表IN PARALLEL?”

是的,几乎可以肯定有一种方法。只需更新数组并为每个数组元素启动Runnable。给每个Runnable引用数组,索引它是计算的,然后让它在没有锁定的情况下进行计算,然后在将结果赋给数组元素时锁定。

注意/免责声明:此答案基于问题中给出的相当不完整的信息......