Mar*_*rta 5 multithreading scala playframework
该项目使用Play framework和Scala语言编写.我已经实施了compile time dependency.我在Play中关注了这个例子:
https://github.com/playframework/play-scala-compile-di-example
看着MyApplicationLoader.scala:
import play.api._
import play.api.routing.Router
class MyApplicationLoader extends ApplicationLoader {
private var components: MyComponents = _
def load(context: ApplicationLoader.Context): Application = {
components = new MyComponents(context)
components.application
}
}
class MyComponents(context: ApplicationLoader.Context)
extends BuiltInComponentsFromContext(context)
with play.filters.HttpFiltersComponents
with _root_.controllers.AssetsComponents {
lazy val homeController = new _root_.controllers.HomeController(controllerComponents)
lazy val router: Router = new _root_.router.Routes(httpErrorHandler, homeController, assets)
}
Run Code Online (Sandbox Code Playgroud)
以及以下代码行:
lazy val homeController = new _root_.controllers.HomeController(controllerComponents)
Run Code Online (Sandbox Code Playgroud)
我的理解是,HomeController第一次HomeController调用只有一个创建的实例.只要应用程序存在,该实例就会存在.这些陈述是否正确?
将HomeController在我的应用程序看起来像这样:
class HomeController{
val request = // some code here
val workflowExecutionResult = Workflow.execute(request)
}
Run Code Online (Sandbox Code Playgroud)
所以Workflow是类型object而不是class.
在Workflow看起来像这样:
object Workflow {
def execute(request: Request) = {
val retrieveCustomersResult = RetrieveCustomers.retrieve()
// some code here
val createRequestResult = CreateRequest.create(request)
// some code here
workflowExecutionResult
}
}
Run Code Online (Sandbox Code Playgroud)
因此,Workflow调用一些域服务,每个域服务都是类型object而不是class.域服务中的所有值都是不可变的,我val到处都在使用.
这足以确保线程安全吗?
我问,因为我习惯于写C# Web APIs一个HomeController看起来像这样的地方:
class HomeControllerInSeeSharpProject{
// some code here
var request = new Request() // more code here
var workflow = new WorkflowInSeeSharpProject()
var workflowExecutionResult = workflow.execute(request)
}
Run Code Online (Sandbox Code Playgroud)
和Workflow看起来像:
public class WorkflowInSeeSharpProject {
public execute(Request request) {
var retrieveCustomers = new RetrieveCustomers()
var retrieveCustomersResult = retrieveCustomers.retrieve()
// some code here
var createRequest = new CreateRequest()
var createRequestResult = createRequest.create(request)
// some code here
return workflowExecutionResult
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在C#项目每次HomeControllerInSeeSharpProject叫的一个新实例WorkflowInSeeSharpProject被创建,所有的域名服务也newed体,然后我可以肯定,国家不能单独的线程之间共享.所以我担心因为我Scala Workflow
和域服务是类型object而不是class可能存在两个请求被发送到HomeController
这两个线程之间共享的情况.
情况可能如此吗?我的应用程序不是线程安全吗?
我已经读过objectScala中的s不是线程安全的,因为它们只有一个实例.但是我也读过,虽然使用vals 不是线程安全的,但是会使应用程序线程安全...
或者也许Play自己有办法解决这个问题?
由于您使用的是编译时依赖项注入,因此您可以控制创建的实例数量,并且在您的情况下HomeController仅创建一次。当请求进来时,这个单个实例将在线程之间共享,因此您实际上必须确保它是线程安全的。will的所有依赖项HomeController也需要是线程安全的,因此object Workflow必须是线程安全的。目前,Workflow没有公开公开任何共享状态,因此它是线程安全的。一般来说,val其中的定义object是线程安全的。
实际上HomeController,行为就像单身人士一样,避免单身人士可能会更安全。例如,默认情况下,Play Framework 使用Guice依赖注入,只要它不是@Singleton. 动机之一是,正如Nio 的回答所建议的那样,无需担心并发保护的状态:
一般来说,最好不要使用@Singleton,除非您对不变性和线程安全性有充分的了解。如果您认为您有 Singleton 的用例,请确保您正在保护任何共享状态。
| 归档时间: |
|
| 查看次数: |
303 次 |
| 最近记录: |