【Scala】Scala ~ 非同期 / Future ~

■ はじめに

GW休み明けに、Scalaで、非同期のコードを書きそうなので予習。

目次

【1】Scala での非同期
 1)Future
 2)scala-async
【2】サンプル
 例1:実験コード
 例2:実験コード(非同期部分のメソッド化)

【1】Scala での非同期

1)Future << ★今回のテーマ
2)scala-async
etc...

1)Future

* scala.concurrent.Future

https://docs.scala-lang.org/ja/overviews/core/futures.html

object Future
https://dotty.epfl.ch/api/scala/concurrent/Future$.html
trait Future[+T] extends Awaitable[T]
https://dotty.epfl.ch/api/scala/concurrent/Future.html

Await.ready

* 処理の結果を待つ

2)scala-async

https://www.baeldung.com/scala/scala-async

【2】サンプル

例1:実験コード

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Main {
  def main(args: Array[String]): Unit = {
    println("Start")

  val future1st: Future[String] = Future {
    println("1st: Hello")
    Thread.sleep(5000) // 5秒待つ
    println("1st: world")
    "1st: Result"
  }

  val future2nd: Future[String] = Future {
    println("2nd: Hello")
    Thread.sleep(1000) // 1秒待つ
    println("2nd: world") 
    "2nd: Result"
  }

  future1st.map(result => println(result))
  future2nd.map(result => println(result))

  println(s"1st: ${future1st.isCompleted} before sleep") 
  println(s"2nd: ${future2nd.isCompleted} before sleep")

  Thread.sleep(7000) // 7秒待つ

  println(s"1st: ${future1st.isCompleted}  after sleep")
  println(s"2nd: ${future2nd.isCompleted}  after sleep")

    println("Done...")
  }
}

出力結果(1回目)

Start
1st: Hello
1st: false before sleep
2nd: Hello
2nd: false before sleep
2nd: world
2nd: Result
1st: world
1st: Result
1st: true  after sleep
2nd: true  after sleep
Done...

出力結果(2回目)

Start
2nd: Hello
1st: false before sleep
1st: Hello
2nd: false before sleep
2nd: world
2nd: Result
1st: world
1st: Result
1st: true  after sleep
2nd: true  after sleep
Done...

例2:実験コード(非同期部分のメソッド化)

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Main {
  def sayHello(name: String, sleepTime: Int=1000): Future[String] = Future {
    println(s"Hello, ${name}")
    Thread.sleep(sleepTime)
    println(s"Bye, ${name}")
    s"Result, ${name}"
  }

  def main(args: Array[String]): Unit = {
    println("Start")
    val future1st = sayHello("Mike", 5000)
    val future2nd = sayHello("Tom")
    future1st.map(result => println(result))
    future2nd.map(result => println(result))

    println(s"1st: ${future1st.isCompleted} before sleep")
    println(s"2nd: ${future2nd.isCompleted} before sleep")

    Thread.sleep(7000)

    println(s"1st: ${future1st.isCompleted} after sleep")
    println(s"2nd: ${future2nd.isCompleted} after sleep")

    println("Done...")
  }
}

出力結果

Start
Hello, Mike
1st: false before sleep
Hello, Tom
2nd: false before sleep
Bye, Tom
Result, Tom
Bye, Mike
Result, Mike
1st: true after sleep
2nd: true after sleep
Done...

参考文献

https://scala-text.github.io/scala_text/future-and-promise.html
https://tech.mamezou00000.com/entry/scala-future
https://doiluxng.hatenablog.com/entry/2018/07/28/225212
https://zenn.dev/at12/articles/48f2be04262f15
https://qiita.com/takayahilton/items/fc71a33e5eb2e25f2592
https://qiita.com/4245Ryomt/items/63bcf0bf0bab3a99f6b5
https://dev.classmethod.jp/articles/scala-concurrent-future/
Futureで非同期に処理を実行する方法|Scalapedia

関連記事

Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Spark ~ FutureAction ~
https://dk521123.hatenablog.com/entry/2023/04/18/234214
Future パターン
https://dk521123.hatenablog.com/entry/2014/01/18/000804