操作演示

简单上手

scala版Future 和java版是一个意思 将任务放在线程池中去执行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.time.LocalTime
import java.util.concurrent.TimeUnit

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success}

// @formatter:off
object Demo01_future extends App{
  import scala.concurrent.ExecutionContext.Implicits.global
  val fnum :Future[Int]= Future { //  非阻塞任务, 可异步获取结果
    TimeUnit.SECONDS.sleep(2)
    LocalTime.now().toSecondOfDay
  }
  fnum.onComplete(result => result match {
    case Success(i) => println(s"回调B-${i}")
    case Failure(e) => e.printStackTrace()
  })

  println(fnum)
  val rst: Int = Await.result(fnum, Duration.create(3, "second"))
  println("阻塞式--获取结果--"+rst)
}

与普通任务的差异

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.time.LocalTime
import java.util.concurrent.TimeUnit

import scala.concurrent.Future

// @formatter:off
object Demo01_future02 extends App{
  import scala.concurrent.ExecutionContext.Implicits.global
  // 阻塞赋值与 非阻塞赋值的使用差异
  println(s"start-秒数--${LocalTime.now().toSecondOfDay}")
  val num = { // 阻塞赋值
    TimeUnit.SECONDS.sleep(2)
    LocalTime.now().toSecondOfDay
  }
  val num2 = Future { //  非阻塞任务, 可异步获取结果
    TimeUnit.SECONDS.sleep(3)
    LocalTime.now().toSecondOfDay
  }
  num2.onSuccess {
    case (result) => println(s"异步回调收到结果-- ${result}")
  }

  println(s"done-秒数--${LocalTime.now().toSecondOfDay}")
  println(s"同步执行,结果-- ${num}")
  println(s"异步未执行完,无结果 -- ${num2}")

  TimeUnit.SECONDS.sleep(4)
  println("执行完,结果--"+num2.value.get.get)
}

运行结果

1
2
3
4
5
6
start-秒数--79375
done-秒数--79378
同步执行,结果-- 79377
异步未执行完,无结果 -- Future(<not completed>)
异步回调收到结果-- 79381
执行完,结果--79381

num同步执行花了2秒 num2是异步任务对耗时无影响

使用返回值的几种方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

import java.util.concurrent.TimeUnit

import scala.concurrent.duration.{Duration, FiniteDuration}
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success, Try}

// @formatter:off
object Demo01_future03 extends App{
  import scala.concurrent.ExecutionContext.Implicits.global
  // 返回值: 阻塞式获取返回值、回调式使用、try

  val f1: Future[Int] = Future {
    TimeUnit.SECONDS.sleep(1) //模拟耗时操作 比如网络请求
    10
  }
  val duration: FiniteDuration = Duration.create(3, "second")
  // 阻塞等待3秒 超时时间
  val rst: Int = Await.result(f1, duration)
  // result 注重返回结果, ready 注重是否完成
  // Await.ready(f1, Duration.create(3, "second"))
  println(s"阻塞获取结果 -- ${rst}")

  // 多个回调函,执行数顺序不保证
  f1.onSuccess{
    case (num) => println(s"回调C-${num}")
  }
  f1.onComplete({
    case Success(num) => println(s"回调A-${num}")
    case Failure(e) => e.printStackTrace()
  })

  f1.onComplete(result => result match {
    case Success(num) => println(s"回调B-${num}")
    case Failure(e) => e.printStackTrace()
  })

  Try(Await.result(f1, duration)) match {
    case Success(num) => println(s"回调RA-${num}")
    case Failure(e) => e match { // 此情况下 仅针对空指针 其他异常都会跳过
      case npe: NullPointerException =>
        println("I'd be amazed if this printed out.")
    }
  }

  Try(Await.ready(f1, duration)) match {
    case Success(f) => f.value.get match {
      case Success(num) => println(s"回调RB-${num}")
      case Failure(e) => 
    }
    case Failure(_) => 
  }

  TimeUnit.SECONDS.sleep(2)
  println("main -- done")
}

Await可以阻塞式获取结果
回调方式可以添加多个回调
Try可以针对异常进行处理

多个future

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.concurrent.TimeUnit

import scala.concurrent.duration._
import scala.concurrent.{Await, Future}

// @formatter:off
object Demo01_future04 extends App{
  import scala.concurrent.ExecutionContext.Implicits.global

  val f1 = Future {
    TimeUnit.SECONDS.sleep(1)
    "f1"
  }
  val f2 = Future {
    TimeUnit.SECONDS.sleep(2)
    "f2"
  }
  val f3 = Future {
    TimeUnit.SECONDS.sleep(3)
    2342
  }

  val f4 = Future.sequence(Seq(f1, f2, f3))
  val results: Seq[Any] = Await.result(f4, 4 seconds)
  val f44: Future[(String, String, Int)] =
    for {
      r2 <- f2
      r3 <- f3
      r1 <- f1
    } yield (r1.take(1), r2.drop(1), r3 + 1)
  val Seq(f1Str, f2Str, f3Int) = Await.result(f4, 4.seconds)

  // 链式创建新future
  val f06 :Future[Int]= f1 map { case one =>
    "oneeee"
  }map { case two :String=>
    22
  }
}

可以把多个fature包装成一个来处理
future可以链式调用