使用控制器内部不是线程安全的库

时间:2015-01-07 21:00:06

标签: scala playframework

我不确定游戏内部的线程是如何工作的,我理解netty使用单个线程但不确定这如何转换为如何调用控制器动作。

class SomeController extends Controller {

  val processor = new PegDownProcessor()  // 

  def index = Action { request => 

    val result = processor.doSomething()

    Ok("hello")
  }

}

pegdown库说实例化PegDownProcessor可能需要100毫秒,并建议在应用程序中使用单个引用。

  

请注意,第一次创建PegDownProcessor时,它可以占用   几百毫秒准备下面的预备   解析器实例。但是,一旦第一个处理器全部建成   进一步的实例化将会很快。此外,您可以重用现有的   PegDownProcessor实例可以随心所欲,只要你阻止   并发访问,既不是PegDownProcessor也不是   底层解析器是线程安全的。

https://github.com/sirthias/pegdown

它还说它不是线程安全的。

上面的用法是否设计正确,我在控制器中使用单个实例作为val,并实际在控制器操作中使用它?

请解释它是否正确,即线程安全或为什么不是?

1 个答案:

答案 0 :(得分:1)

可以从多个线程调用播放操作。

快速解决方案突然出现在我脑海中: 您可以创建一个处理器池。该池将是线程安全的并且将包含给定数量的处理器(您可以动态地或基于您拥有的CPU / RAM分配处理器的数量)。当请求进入时,池将其放入(FIFO)队列(当然,您应该使用线程安全的队列实现)。每个处理器都在自己的线程上运行,当一个完成一个作业时,它会检查队列中的新作业。池的enqueue方法返回Future,在处理任务时解析。 Play支持控制器方法的异步结果,因此这也适用于Play。

类似的解决方案是使用Akka及其actor池功能,它基本上以更通用的方式实现上述方法。因为actor是单线程的,所以每个actor都有一个对处理器的引用,并且只会像在单个线程上那样做。 Akka允许使用高级选项,例如定义调度方法,并且非常适合Play堆栈。 Akka本身几乎没有任何开销,你可以创建成千上万的演员而没有任何性能问题。