玩 Scala 和线程安全

2024-04-24

该项目是使用编写的Play framework and Scala语言。 我已经实施了compile time dependency。 我按照 Play 中的这个例子进行操作:

https://github.com/playframework/play-scala-compile-di-example 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叫做。 只要应用程序存在,该实例就会存在。这些说法正确吗?

The HomeController在我的应用程序中看起来像这样:

class HomeController{

   val request = // some code here

   val workflowExecutionResult = Workflow.execute(request)

}

So Workflow属于类型object并不是class.

The Workflow看起来像这样:

object Workflow {
  def execute(request: Request) = {

    val retrieveCustomersResult = RetrieveCustomers.retrieve() 
    // some code here

    val createRequestResult = CreateRequest.create(request)
    // some code here

    workflowExecutionResult
  }
}

So 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)
}

and a 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
  }
}

所以在 C# 项目中每次HomeControllerInSeeSharpProject被称为一个新实例WorkflowInSeeSharpProject已创建并且所有域服务 也是更新的,然后我可以确定状态不能在单独的线程之间共享。所以我担心因为我的Scala Workflow域服务的类型为object并不是class可能存在这样的情况:两个请求被发送到HomeController并且状态在这两个线程之间共享。

可以这样吗?我的应用程序不是线程安全的吗?

我读过objectScala 中的 s 不是线程安全的,因为它们只有单个实例。不过我也读过,虽然 它们不是线程安全的vals 将使应用程序线程安全......

或者可能Play本身有办法解决这个问题吗?


因为您正在使用编译时依赖项注入,所以您可以控制创建的实例数量,并且在您的情况下HomeController仅创建一次。当请求进来时,这个单个实例将在线程之间共享,因此您实际上必须确保它是线程安全的。的所有依赖项HomeController还需要是线程安全的,因此object Workflow必须是线程安全的。现在,Workflow不公开暴露任何共享状态,因此它是线程安全的。一般来说,val内的定义object are 线程安全 https://stackoverflow.com/questions/23047657/val-at-object-level-and-thread-safety-in-scala#answer-23048497.

有效HomeController表现得像单身人士,避免单身人士可能会更安全。例如,默认情况下,Play Framework 使用Guice https://github.com/google/guice/wiki/Scopes依赖注入,只要它不是一个请求,它就会为每个请求创建一个新的控制器实例@Singleton。动机之一是,如建议的那样,无需担心并发保护的状态尼奥的回答 https://stackoverflow.com/questions/40643080/why-use-singletone-controllers-in-play-2-5#answer-40653182:

一般来说,最好不要使用@Singleton,除非你有 对不变性和线程安全性有一个公平的理解。如果你认为 你有一个 Singleton 的用例,但只需确保你是 保护任何共享状态。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

玩 Scala 和线程安全 的相关文章

随机推荐

  • Unity 3 按约定配置未在 Web 项目中找到类型

    我正在尝试使此约定配置正常工作 但我的 ASP NET MVC5 项目遇到问题 我在 Application Start 方法中添加了以下内容并将其连接到 DependencyResolver public static IUnityCon
  • 在使用 Java 8 重新协商 TLS_1.2 期间,服务器证书更改受到限制

    我对 SSL 还很陌生 并且遇到了一些看似已知的问题 我的应用程序是 SSL 客户端 并调用另一个启用双向 SSL 的组件 两个组件中的证书都是正确的 并且连接有时工作正常 每个服务器都有自己的服务器证书和私钥 但根证书和中间证书相同 服务
  • 如何迭代每隔一个数字

    阅读文档时 我注意到一句话 Rust 没有C stylefor 循环 所以 我想知道 如何制作一个相当于for i 0 i lt 10 i 2 我能想到的方法是这样的 for i in 0 10 if i 2 0 Do stuff Or e
  • 如何获取2d dict python中的所有键

    我有一本形式词典 d 123 2 1 3 1 124 3 1 125 2 1 126 1 1 那么 让我们看看二阶键 123 gt 2 3 124 gt 3 125 gt 2 126 gt 1 所以唯一的二阶键的总数是 1 2 3 现在 我
  • 在 Flash 对象上方显示图像

    我在这里面临着一个棘手的情况 这就是问题 我有一个 Flash 对象 我想在其上显示图像这些是我尝试过的技巧 1 玩转z index 没用 2 将wmode参数设置为透明 不透明 同样没有用 3 使用javascript并仅在页面加载后显示
  • 没有这样的模块“RestKit”与 cocoapods 和 swift

    我在一个全新的项目中遇到了这个问题 RestKit 和 Facebook SDK 都会出现此问题 奇怪的是 SwiftyJSON 工作得很好 我创建了一个全新的 swift 项目和一个 Podfile 其中包含 source https g
  • 当 CURLOPT_HTTPHEADER 需要“Content-Length”时

    我的应用程序的客户端中有此代码 ch curl init url curl setopt ch CURLOPT CUSTOMREQUEST GET curl setopt ch CURLOPT RETURNTRANSFER true cur
  • Ruby on Rails 过滤返回模型对象的属性

    我正在为 Rails 应用程序创建 API 我想返回User用于 API 调用但没有的对象crypted password salt or login token属性 有没有办法做这样的事情 do api fetch user u user
  • 命名空间 + 函数与类上的静态方法

    假设我已经或将要编写一组相关函数 假设它们与数学相关 从组织上来说 我应该 编写这些函数并将它们放入我的MyMath命名空间并通过引用它们MyMath XYZ 创建一个名为MyMath并使这些方法静态并引用类似的MyMath XYZ 为什么
  • iOS-示例中的协议和委托

    好吧 我正在寻找 但没有任何方法对我有用 以下代码基于许多教程和苹果文档 但我无法让它工作 有人可以帮忙吗 代码崩溃于 obj delegatee self 在 B h 类中 respondsToSelector 和 PerformSele
  • 尝试使用工作台将 postgresql 数据库迁移到 mysql 时出错

    我正在尝试按照本教程将 postgresql 数据库迁移到 mysql http mysqlworkbench org 2012 11 how to migrate postgresql databases to mysql using t
  • Healpy python-3..4 在 ubuntu-14.04 上的安装问题

    我是 ubuntu 新手 在 lenovo t410 上使用 ubuntu 14 04 和 python 3 4 为了安装 Healpy 我遵循了以下步骤 我已经使用安装了 python3 dev 包 sudo apt get instal
  • Visual Studio Code / powershell 命令历史记录向上键

    我可以通过什么方式在 Visual Studio Code 中记录之前输入的命令 例如 当我按下向上键时 我可以向上浏览之前的所有命令 如果可能的话 我想将这些记录到文件中 它们本地存储在哪里 我可以用节点之类的东西记录它吗 实际上 我自己
  • 在页面显示到屏幕之前删除 DOM 元素(在 Chrome 扩展中)

    我正在尝试创建一个扩展 该扩展将在页面显示到屏幕上之前删除某些页面元素 按 id 或类 我尝试在文档上使用事件侦听器 以 DOMContentLoaded 作为事件 但 javascript 似乎在页面显示给用户后执行 然后删除它 所以它不
  • 基于 Django 类的视图和表单集

    我有一个基于类的视图称为OrganizationsCreateView它包括附加到模型表单的表单集作为该表单的实例变量 当用户输入数据时 这可以正常工作 可以很好地创建一个新对象 当用户想要向表单集中添加其他行时 我有一个提交按钮 可以触发
  • iOS glGenerateMipmap 是同步的,还是可能是异步的?

    我正在开发一个在 OpenGL ES 中使用大纹理的 iPad 应用程序 当场景首次加载时 我在天花板上看到了几帧的大型黑色伪像 如下图所示 就好像更高级别的 mipmap 尚未填充 在后续帧中 天花板正确显示 当我开始使用 mipmapp
  • 如何使用 mongocxx c++ 驱动程序递归生成 Mongodb 文档?

    如何使用 mongocxx c 驱动程序递归生成 Mongodb 文档 1 我使用 mongocxx c 驱动程序 v 3 和 c 11 2 这是我的 main cpp 方法 它解析十六进制字符串并生成 mongocxx 代码 如下所示 控
  • 在 Trie 中插入值

    我在 SML 目录中找到了 Trie 的实现 signature DICT sig type key string concrete type type a entry key a concrete type type a dict abs
  • Android 无法初始化 Visualizer 引擎,错误:-4

    我有一个错误 public class VisualizerCapture extends Activity implements Visualizer OnDataCaptureListener private Visualizer mV
  • 玩 Scala 和线程安全

    该项目是使用编写的Play framework and Scala语言 我已经实施了compile time dependency 我按照 Play 中的这个例子进行操作 https github com playframework pla