Play Framework - System.loadLibrary()每个线程只有一次

时间:2013-11-06 21:36:55

标签: java c++ scala opencv playframework

我正在使用Play Framework 2.1编写一个webapp,它使用OpenCV(2.4.6)库。我编译OpenCV并获得最终的.jar没有任何问题,但有一句话让我在the Java/Scala tutorial担心OpenCV:

  

请注意对System.loadLibrary(Core.NATIVE_LIBRARY_NAME)的通话。这个   在使用之前,每个Java进程必须执行一次命令   任何原生的OpenCV方法。如果你不打电话,你会得到   不满意的链接错误。如果您尝试加载,也会出错   OpenCV已经加载。

我知道Play Framework是多线程的,线程在请求​​之间重用。有没有办法让我在每个单独的线程产生时调用loadLibrary函数?或者我误解了线程池的工作方式,我应该根据请求加载一次库?这里的正确方法是什么?

[编辑:]我发现我可以将System.loadLibrary代码放在全局配置类中,这将使所有线程共享库。该库不是线程安全的,所以我认为如果我这样做只是偶然发生......

1 个答案:

答案 0 :(得分:0)

似乎没有问题 - “每个Java 进程必须执行一次此命令” - 只需在应用程序启动时调用一次就可以了,您不必担心不同的线程

奖励:可以检查库是否已经加载(即使它是完全没必要的),即:

 def loadedLibs: Seq[String] = {
    val libs = classOf[ClassLoader].getDeclaredField("loadedLibraryNames")
    libs.setAccessible(true)
    import scala.collection.JavaConverters._
    libs.get(ClassLoader.getSystemClassLoader())
      .asInstanceOf[java.util.Vector[String]]
      .asScala
  }

  def loadOpenCVOnDemand(): Unit = {
    val isLoaded = loadedLibs.map(str => str contains "opencv").reduce((x, y) => x || y)
    if(!isLoaded) {
      System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
    }
  }

另一个问题是,是否可以同时调用本机库的函数。在OpenCV中,它根本不是问题:

  

当前的OpenCV实现完全可以重新输入。那就是   相同的函数,类实例的相同常量方法,或者   可以调用不同类实例的相同非常量方法   来自不同的线程。此外,可以使用相同的cv :: Mat   不同的线程因为引用计数操作使用了   特定于体系结构的原子指令。