twitter的Future的简单使用

直接上示例:
获取一个Futute:
def getFuture3: Future[String] = {
    FuturePool.unboundedPool {
        println("begin future3")
        println(Thread.currentThread().getName)
        TimeUnit.SECONDS.sleep(3)
        println("future3 over.")
        "zero"
    }
}
类似Java,在线程池里提交一个任务,返回值即 { } 中的值。注意这里的线程池是twitter中的UnboundedFuturePool(无界任务池),当然可以指定线程池:
def getFuture2: Future[String] = {
    val executors = Executors.newFixedThreadPool(3)
    val futurePool: ExecutorServiceFuturePool = FuturePool.apply(executors)
    futurePool.apply({
        //使用的是自定义的pool
        println("begin future2")
        println("future2 --- " + Thread.currentThread().getName)
        TimeUnit.SECONDS.sleep(3)
        println("future2 over.")
        "zero"
    })
}
这里指定了executors线程池,那个任务执行由指定池中的线程去完成。如果需要get这个future的值:
val result = Await.result(getFuture3, DEFAULT_TIMEOUT)

组合两个future的结果为另一个future,test2也是同样:
def test1: Unit = {
    val future3 = for (f1 <- getFuture1; f2 <- getFuture2) yield (f1 + " " + f2)
    println("await")
    val result = Await.result(future3, DEFAULT_TIMEOUT)
    println(result)
}
运行结果:
begin future1
await
future1 --- UnboundedFuturePool-1
future1 over.
begin future2
future2 --- pool-1-thread-1
future2 over.
zero zero
从运行结果,效果上看for中内容还是串行执行,但 future3 与 println("await") 是并行执行的,方式二:
def combine(a: String, b: String): Future[String] = {
    FuturePool.unboundedPool {
        println(s"combine $a + $b")
        TimeUnit.SECONDS.sleep(1)
        a + "-" + b
    }
}

def test2: Unit = {
    val result =
        for (
            result1 <- getFuture1;
            result2 <- getFuture2;
            combineResult <- combine(result1, result2)
        ) yield combineResult

    println("await")
    val v = Await.result(result)
    println(v)
}
运行结果:
begin future1
future1 --- UnboundedFuturePool-1
await
future1 over.
begin future2
future2 --- pool-1-thread-1
future2 over.
combine zero + zero
zero-zero
可以看到,使用for来组合两个future的结果时,得是getFuture1完成后getFuture2才开始,是一个串行调用。有其他方式么?

def test3: Unit = {
    val future3 = Future.join(getFuture1, getFuture2)
    val f = future3 flatMap { e =>
        combine(e._1, e._2)
    }
    println("await")
    println(Await.result(f))
}
运行结果:
begin future1
future1 --- UnboundedFuturePool-1
begin future2
future2 --- pool-1-thread-1
await
future1 over.
future2 over.
combine zero + zero
zero-zero
可以看出Future.join比for要好,是真正的异步并发。当然Future还可以处理异常:
def fail(a: String, b: String): Future[String] = {
    FuturePool.unboundedPool {
        println("fail operation.")
        TimeUnit.SECONDS.sleep(1)
        println("throwing exception!")
        throw new Exception("Exception.")
    }
}

//抛出异常并被捕获
def test4: Unit = {
    val result = Future.join(getFuture1, fail("a", "b")).flatMap {
        case (result1, result2) => combine(result1, result2)
    }.ensure {
        //Ensure is executed both in case of succes or failure.
        println("---ensure----")
    }.rescue {
        //Only execute when exception occurred
        case e: Exception => {
            println(e.getMessage)
            Future.False
        }
    }
    println("await")
    println(Await.result(result))
}
运行结果:
fail operation.
begin future1
future1 --- UnboundedFuturePool-1
await
throwing exception!
---ensure----
Exception.
false
rescue块可以处理异常,也仅在异常发生时执行,ensure无论是正常还是异常都会执行。

你可能感兴趣的:(twitter的Future的简单使用)