【问题标题】:Concurrency in Play for ScalaPlay for Scala 中的并发性
【发布时间】:2016-11-07 12:10:58
【问题描述】:

假设您在 Play 网络应用程序中有以下代码:

class MyClass extends Controller  {

  def myMethod = Action {

      var a = 0

      while ( a < 1000 ) {
         println( "Value of a: " + a );
         a = a + 1;
      }

  }

}

如果两个用户/浏览器调用相同的方法,我会出现竞争条件吗?如果是,如何避免?

【问题讨论】:

  • 在这种情况下,变量a 是执行ActionFuture 的线程的本地变量,所以答案是。如果a 被声明为控制器的字段,那么它当然会有竞争条件。另一种引入问题的方法是让更多Futures/Threads/Actors参与更改a
  • @insan-e 但这仅适用于控制器是单例的情况。如果它是按请求创建的,那么应该没有问题。

标签: scala playframework playframework-2.5


【解决方案1】:

没有。

a 是根据请求创建的。

如果您要返回 Futures,还请检查异步操作。

【讨论】:

    【解决方案2】:

    这将始终打印Value of a: 0,因为a 是一个局部变量,您在每次请求时都使用0 对其进行初始化。

    如果您在方法范围之外声明它,那么它可以用作计数器(如果您的控制器是单例),但是是的,您可能会遇到竞争条件。

    解决它的一种方法是在控制器中使用 AtomicInteger 的单例实例。您可以在此处查看更多详细信息:https://github.com/zoltanmaric/slike/blob/master/app/controllers/CountController.scala

    【讨论】:

    • 虽然这在技术上可能可行,但我不会向初学者推荐/建议此类事情。特别是如果我们在这里谈论的是一个固有的无状态框架(至少这是目标)。
    • @rethab 我完全同意你的看法
    • 如果我在循环中增加a,你为什么说you're initializing it with 0 on each request
    • @ps0604 实际上我刚刚意识到我的答案完全错误。里斯布拉德伯里是对的。没有竞争条件。您为每个请求创建一个局部变量a,并将其计数到1000。这完全没问题。我假设您正在尝试计算对控制器的请求数,这就是我建议使用 CountController 的原因。
    猜你喜欢
    • 2016-11-13
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2021-02-13
    • 2016-11-10
    • 2018-08-03
    • 1970-01-01
    相关资源
    最近更新 更多