2016-11-07 2 views
1

Angenommen, Sie den folgenden Code in einer Play-Web-Anwendung haben:Concurrency in Play für Scala

class MyClass extends Controller { 

    def myMethod = Action { 

     var a = 0 

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

    } 

} 

Könnte ich eine Race-Bedingung, wenn zwei Benutzer/Browser die gleiche Methode aufrufen? Wenn ja, wie kann man es vermeiden?

+0

In diesem Fall ist die Variable "a" lokal zu thread, die die "Zukunft" der Aktion ausführt, so ist die Antwort ** nein **. Wenn das "a" als das * Feld * des Controllers deklariert würde, hätte es natürlich einen Wettlaufzustand. Eine weitere Möglichkeit, Probleme einzuführen, besteht darin, mehr 'Future' /' Thread'/'Actors' in die Veränderung von' a' einzubeziehen. –

+0

@ insan-e aber das ist nur anwendbar, wenn der Controller ein Singleton ist. Wenn es stattdessen pro Anfrage erstellt wird, sollten keine Probleme auftreten. –

Antwort

3

Nr

a pro Anfrage erstellt.

Überprüfen Sie auch die Aktion async, wenn Sie Futures zurückgeben.

2

Dies wird immer Value of a: 0 drucken, da a eine lokale Variable ist und Sie es bei jeder Anfrage mit 0 initialisieren.

Wenn Sie es außerhalb des Geltungsbereichs Ihrer Methode deklariert haben, könnte es als Zähler funktionieren (wenn Ihr Controller ein Singleton ist), aber ja, Sie hätten potentielle Rennbedingungen.

Eine Möglichkeit, dies zu lösen, ist die Verwendung einer Singleton-Instanz eines AtomicInteger in Ihrem Controller. Sie können mehr Details hier sehen: https://github.com/zoltanmaric/slike/blob/master/app/controllers/CountController.scala

+1

Während das wahrscheinlich technisch funktionieren würde, würde ich solche Dinge Anfängern nicht empfehlen. Vor allem, wenn wir hier über einen inhärent staatenlosen Rahmen sprechen (zumindest das ist das Ziel). – rethab

+0

@rethab Ich stimme dir voll und ganz zu –

+0

Warum sagst du 'du initialisierst es mit 0 bei jeder Anfrage' wenn ich' a' in der Schleife inkrementiere? – ps0604