Play Framework - System.loadLibrary () только один раз для потока

0

Я пишу webapp, используя Play Framework 2.1, который использует библиотеки OpenCV (2.4.6). У меня не было никаких проблем с компиляцией OpenCV и получением окончательного.jar, но есть одно замечание, которое меня беспокоит в учебнике Java/Scala для OpenCV:

Обратите внимание на вызов в System.loadLibrary(Core.NATIVE_LIBRARY_NAME). Эта команда должна выполняться ровно один раз на Java-процесс до использования любых собственных методов OpenCV. Если вы его не назовете, вы получите ошибки UnsatisfiedLink. Вы также получите ошибки, если попытаетесь загрузить OpenCV, когда он уже был загружен.

Я знаю, что Play Framework многопоточен, и потоки повторно используются между запросами. Есть ли способ вызвать функцию loadLibrary когда loadLibrary отдельные потоки? Или я не понимаю, как работает пул потоков, и я должен загрузить библиотеку один раз за запрос? Каков правильный подход?

[Edit:] Я понял, что могу поместить код System.loadLibrary в глобальный класс конфигурации, который заставит все потоки совместно использовать библиотеку. Библиотека не является потокобезопасной, поэтому я думаю, что это просто несчастный случай, когда я это сделаю...

Теги:
opencv
playframework

1 ответ

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 может использоваться в разных потоках, потому что операции подсчета ссылок используют атомарные инструкции, специфичные для архитектуры.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню