该项目是使用Play framework和Scala语言编写的。我已经实现了编译时依赖关系。我在游戏中遵循了以下示例:
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)
}
以及以下代码行:
lazy val homeController = new _root_.controllers.HomeController(controllerComponents)
我的理解是,在第一次调用HomeController时,只创建了一个HomeController实例。该实例的寿命与应用程序的寿命一样长。这些说法正确吗?
我的应用程序中的HomeController如下所示:
class HomeController{
val request = // some code here
val workflowExecutionResult = Workflow.execute(request)
}
因此,工作流属于对象类型,而不是类。
工作流如下所示:
object Workflow {
def execute(request: Request) = {
val retrieveCustomersResult = RetrieveCustomers.retrieve()
// some code here
val createRequestResult = CreateRequest.create(request)
// some code here
workflowExecutionResult
}
}
因此,工作流调用几个域服务,每个域服务的类型都是对象,而不是类。域服务中的所有值都是不可变的,我在任何地方都使用val。
这是否足以确保Thread安全?
我在问,因为我习惯于编写C#Web API,其中一个家庭控制器应该是这样的:
class HomeControllerInSeeSharpProject{
// some code here
var request = new Request() // more code here
var workflow = new WorkflowInSeeSharpProject()
var workflowExecutionResult = workflow.execute(request)
}
工作流
如下所示:
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
}
}
因此,在C#项目中,每次调用HomeControlllerInSeeSharpProject
时,都会创建Workflow InSeeSharpProject
的新实例,并且所有域服务也是更新的,然后我可以确定状态不能在单独的线程之间共享。所以我担心,因为我的Scala
Workflow
和域服务的类型是对象
而不是类
,可能会出现两个请求被发送到HomeController
并且状态在这两个线程之间共享的情况。
会是这样吗?我的应用程序不是线程安全的吗?
我读到Scala中的对象
不是线程安全的,因为它们只有单个实例。然而,我也读到,虽然它们不是线程安全的,但使用val
s将使应用程序线程安全...
或者Play
本身有办法解决这个问题?
因为您使用的是编译时依赖项注入,所以您可以控制创建的实例数,在您的情况下,HomeController只创建一次。当请求传入时,这个实例将在线程之间共享,因此您必须确保它是线程安全的。HomeController的所有依赖项也需要是线程安全的,因此对象工作流必须是线程安全的。目前,工作流未公开公开任何共享状态,因此它是线程安全的。通常,对象中的定义是线程安全的。
实际上,HomeController
的行为就像单例,避免单例可能更安全。例如,默认情况下,Play Framework使用Guice依赖注入,只要它不是@Singleton
,它就会为每个请求创建一个新的控制器实例。一个动机是,正如Nio的回答所建议的那样,对并发保护的担忧更少:
一般来说,最好不要使用@Singleton,除非您对不变性和线程安全有相当的了解。如果您认为您有Singleton的用例,请确保您正在保护任何共享状态。
问题内容: 我经常听到对Swing库中缺乏线程安全性的批评。但是,我不确定自己将在自己的代码中执行的操作会导致问题: 在什么情况下,Swing不是线程安全的事实起作用? 我应该积极避免做什么? 问题答案: 切勿执行长时间运行的任务以响应按钮,事件等,因为这些事件在事件线程上。如果您阻止事件线程,则整个GUI将完全无响应,从而使用户感到非常生气。这就是为什么Swing看起来缓慢又硬朗。 使用线程,执
将Scala的值类与Mockito mock(匹配器)一起使用会导致NullPointerException,请参见以下示例: 结果: 任何提示在这里可以做些什么?
问题内容: 我正在寻找关于线程安全信息和。官方文档(http://docs.python.org/library/urllib2.html和http://docs.python.org/library/httplib.html)缺少有关此主题的任何信息。那里甚至没有提到 线程 一词… 更新 好的,它们不是线程安全的。使它们具有线程安全性需要什么,或者存在使它们具有线程安全性的情况?我问是因为好像
问题内容: 在多个类中,是否是线程安全的? 问题答案: 尽管EntityManager实现本身不是线程安全的,但是Java EE容器注入了一个代理,该代理将所有方法调用委托给与事务绑定的EntityManager。因此,每个事务都使用其自己的EntityManager实例。至少对于事务范围的持久性上下文而言,这是正确的(默认设置)。 如果容器将在每个bean中注入EntityManager的新实例
我的Spring项目中有一个简单的: 并按如下方式使用: 我是否必须注意线程安全并使同步(因为不是线程安全的)?我不确定到底是如何工作的--它是否只创建跨所有线程的单个序列化实例?还是为每个转换创建单独的实例?
我试图理解如果下面是线程安全的,它是由另一个开发人员编写的代码,我已经继承和不再与我们在一起。 我有一个BaseProvider类,它实际上是一个消息缓存,由LinkedBlockingQueue表示。该类将传入的消息存储在队列中。 我有一组读此队列的辅助线程。因此,LinkedBlockingQueue是线程安全的。 正如您所注意到的,每个辅助线程都可以访问所有的提供者,所以当一个辅助线程遍历所