Skip to content

Instantly share code, notes, and snippets.

@rice10t
Created August 17, 2016 07:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rice10t/ae63ccf642dad9128e8a3ce29c4c5851 to your computer and use it in GitHub Desktop.
Save rice10t/ae63ccf642dad9128e8a3ce29c4c5851 to your computer and use it in GitHub Desktop.
Futureのれんしゅう
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
object FutureExamples {
def multipleFuture(): Unit = {
val h1 = FutureCreator.heavy("heavy1")
val h2 = FutureCreator.heavy("heavy2")
val l1 = FutureCreator.light("light1")
val l2 = FutureCreator.light("light2")
val futures = Future.sequence(Seq(h1, h2, l1, l2))
val result = Await.result(futures, Duration.Inf)
println(s"Result: $result")
}
def sequentialExec(): Unit = {
val future = (for {
result1 <- FutureCreator.maybeSuccess("future1", 1)
result2 <- FutureCreator.maybeSuccess("future2", result1)
} yield {
s"$result2"
}) recover { case t =>
println(s"Catching Exception: ${t.getMessage}")
0
}
val resultText = Await.result(future, Duration.Inf)
println(s"Result: $resultText")
}
}
object FutureCreator {
def light(name: String): Future[String] = Future {
Thread.sleep(500)
println(s"$name finished")
name
}
def heavy(name: String): Future[String] = Future {
Thread.sleep(1000)
println(s"$name finished")
name
}
def maybeSuccess(name: String, value: Int): Future[Int] = Future {
val zeroToTwo = Math.floor(Math.random * 3).toInt
// 0以外(1か2)の場合成功
// 2/3の確率で成功
val succeeded = zeroToTwo != 0
if (succeeded) {
Thread.sleep(600)
val result = value + 1
println(s"$name has successfully completed with value $result")
result
} else {
println(s"$name failed")
throw new Exception(s"Future failed at $name")
}
}
}
object Main extends App {
Timer.start("Timer1") { timer =>
FutureExamples.multipleFuture()
}
// Timer1 started
// ---------------Timer Start---------------
// light1 finished
// light2 finished
// heavy2 finished
// heavy1 finished
// Result: List(heavy1, heavy2, light1, light2)
// ---------------Timer End-----------------
// Timer1 finished in 1152ms
Timer.start("Timer2") { timer =>
FutureExamples.sequentialExec()
}
// future1で失敗
// Timer2 started
// ---------------Timer Start---------------
// future1 failed
// Catching Exception: Future failed at future1
// Result: 0
// ---------------Timer End-----------------
// Timer2 finished in 5ms
// future2で失敗
// Timer2 started
// ---------------Timer Start---------------
// future1 has successfully completed with value 2
// future2 failed
// Catching Exception: Future failed at future2
// Result: 0
// ---------------Timer End-----------------
// Timer2 finished in 606ms
// 成功
// Timer2 started
// ---------------Timer Start---------------
// future1 has successfully completed with value 2
// future2 has successfully completed with value 3
// Result: 3
// ---------------Timer End-----------------
// Timer2 finished in 1202ms
}
class Timer(val name: String) {
private val startTime = System.currentTimeMillis()
def calc: Long = System.currentTimeMillis() - startTime
override def toString: String = s"$name finished in " + calc + "ms"
}
object Timer {
def apply(timerName: String): Timer = new Timer(timerName)
def start(timerName: String = "Timer")(f: Timer => Unit): Unit = {
val timer = Timer(timerName)
println(s"${timer.name} started")
println("---------------Timer Start---------------")
f(timer)
println("---------------Timer End-----------------")
println(timer.toString)
}
}
@rice10t
Copy link
Author

rice10t commented Sep 15, 2016

たぶんJVMがどうのこうのでTimer1に時間がかかりすぎてるっぽいけどまあいいか

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment