2017-07-05 2 views
0

In diesem Beispiel habe ich eine Race-Bedingung haben, die Zeichenfolge s am Ende des Programms zu vermeiden, mit @ und # ersetzt gedruckt werden soll:Sequencing Futures Race-Bedingung

object TestFutures extends App { 

    var s = "THIS IS A STRING" 

    val f0 = Future { 0 } 
    val f1 = Future { 1 } 
    val fx = Seq(f0,f1) 

    fx.map { 
    seq => seq.map { i => 
      println("BEFORE ---> " + s) 
      if (i == 0) 
       s = s.replace ("T", "@") 
      else 
       s = s.replace ("I", "#") 
      println("AFTER ---> " + s) 
     } 
    } 


    Thread.sleep(5000) 
} 

Aber der Code druckt

BEFORE ---> THIS IS A STRING 
BEFORE ---> THIS IS A STRING 
AFTER ---> TH#S #S A STR#NG 
AFTER ---> TH#S #S A STR#NG 

Wie vermeidet man diese Wettlaufsituation? Wie ändere ich die Zeichenfolge?

Antwort

1

Der einzige sichere Weg, um Rennbedingungen zu vermeiden, ist kein veränderbarer Zustand. So etwas würde funktionieren:

val s = "THIS IS A STRING" 
Future 
    .sequence(Seq(Future(0), Future(1))) 
    .map { 
     _.foldLeft(s) { 
     case (s, 0) => s.replaceAll("T", "@") 
     case (s, _) => s.replaceAll("I", "#") 
    } 
    }.andThen { 
    case Success(str) => println("RESULT: " + str) 
    }