Scala Future

智数星罗盘
• 阅读 2084

Future

  • scala.concurrent.Future 异步执行代码块

    import java.time._
    import scala.concurrent._
    import ExecutionContext.Implicits.global // 全局线程池
    Future {
            Thread.sleep(10000)
            println(s"This is the future at ${LocalTime.now}")
    }
    println(s"This is the present at ${LocalTime.now}")
  • 监听结果(阻塞)

    import scala.concurrent.duration._
    val f = Future { Thread.sleep(10000); 42 }
    val result = Await.result(f, 10.seconds) //阻塞10s
    
    val f = Future { ... }
    Await.ready(f, 10.seconds)
    val Some(t): Option[Try[T]] = f.value
    
    t match {
            case Success(v) => println(s"The answer is $v")
            case Failure(ex) => println(ex.getMessage)
    }

ready()

  • 到达等待时间无结果时,会抛出异常 TimeoutException
  • 任务抛出的异常时,result() 会再次抛出异常, ready() 可获取结果
  • 回调

    val f = Future { 
            Thread.sleep(10000)
            if (random() < 0.5) throw new Exception
            42
    }
    f.onComplete {
            case Success(v) => println(s"The answer is $v")
            case Failure(ex) => println(ex.getMessage)
    }
  • 问题:1.回调地狱;2.执行顺序无法预知

    val future1 = Future { getData1() }
    val future2 = Future { getData2() }
    future1 onComplete {
            case Success(n1) =>
                    future2 onComplete {
                            case Success(n2) => {
                                    val n = n1 + n2
                                            println(s"Result: $n")
                                    }
                            case Failure(ex) => ...
                    }
            case Failure(ex) => ...
    }
    将 Future 看作集合
    // val 会立即执行,def 调用时执行
    val future1 = Future { getData1() }
    val future2 = Future { getData2() }
    // 都获取到结果时,才会进行计算
    val combined = for (n1 <- future1; n2 <- future2) yield n1 + n2
  • Promise

    • 与 Java 8 中的 CompletableFuture 类似
    • Future 只读,在任务完成时隐式设置结果值;Promise 类似,但结果值可显式设置

      // Future
      def computeAnswer(arg: String) = Future {
          val n = workHard(arg)
          n
      }
      
      // Promise
      def computeAnswer(arg: String) = {
          val p = Promise[Int]()
          Future {
              val n = workHard(arg)
              // 显式设置结果
              p.success(n)
              workOnSomethingElse()
          }
          // 立即返回该 Promise 对应的 Future
          p.future
      }
      
      // 多个任务对应一个 Promise
      val p = Promise[Int]()
      Future {
          var n = workHard(arg)
          // 若 Promise 未完成则接受结果并返回 true;否则忽略结果并返回 false
          p.trySuccess(n)
      }
      Future {
          var n = workSmart(arg)
          p.trySuccess(n)
      }
  • 执行上下文

    • 默认执行在全局的 fork-join 线程池(默认大小为核数),适用于计算密集型任务
    • 对于阻塞型/IO密集型的任务,可使用 Java 的 Executors

      // 隐式声明,或者使用 Future.apply 显式声明
      val pool = Executors.newCachedThreadPool()
      implicit val ec = ExecutionContext.fromExecutor(pool)
      
      val f = Future {
          val url = ...
          blocking {
              val contents = Source.fromURL(url).mkString
              ...
          }
      }
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
4年前
Netty概念之 Future 和 Promise
(一)jdk中future和netty中future的比较jdk中future://取消异步操作booleancancel(booleanmayInterruptIfRunning);//异步操作是否取消booleanisCancell
Stella981 Stella981
4年前
ExecutorService 线程池 (转发)
1.ExecutorServicejava.util.concurrent.ExecutorService接口。用来设置线程池并执行多线程任务。它有以下几个方法。Future<?java.util.concurrent.ExecutorService.submit(Runnabletask)提交任务并执行,返回代表这个任务的future
Stella981 Stella981
4年前
Spark框架:Win10系统下搭建Scala开发环境
一、Scala环境基础Scala对Java相关的类,接口进行了包装,所以依赖Jvm环境。Jdk1.8scala依赖scala2.11安装版本idea2017.3开发工具二、配置Scala解压版1)注意路径无空格和中文!(http
Wesley13 Wesley13
4年前
ES6 新增的数组的方法
给定一个数组letlist\//wu:武力zhi:智力{id:1,name:'张飞',wu:97,zhi:10},{id:2,name:'诸葛亮',wu:55,zhi:99},{id:3,name:'赵云',wu:97,zhi:66},{id:4,na
Stella981 Stella981
4年前
Scala之美
1\.介绍      Scala语言拥有很强的表达能力,语法简洁,很接近人类的思考方式。利用map、flatMap方法做数据转换时,层层递进的演算方式,很像是在画流程图,中间没有停顿,思绪很流畅,不会被无关的变量声明、初始化等琐事打断。Scala中的Future可以让你非常灵活的使用线程,而不需要关注底层的线程管理问题,Scala已经为你处
Stella981 Stella981
4年前
PlayScala实战
1问题背景我们先看一下Play中Action代码的基本结构:defgreetingAction.async{implicitrequestfor{r1<Future.successful("result")r2<Future.successful
Stella981 Stella981
4年前
Elasticsearch自定义Future的源码分析
Elasticsearch自定义Future的实现源码分析1、Future自定义实现类实现类有3个,PlainActionFuture 、PlainTransportFuture、PlainListenableActionFuture。类关系如图:!(https://img2018.cnblogs.com/blog/1706061
并发编程-ExecutorCompletionService解析
1、简单介绍我们在并发编程中,目前大部分做法都是将任务添加到线程池中,并拿到Future对象,将其添加到集合中,等所有任务都添加到线程池后,在通过遍历Future集合,调用future.get()来获取每个任务的结果,这样可以使得先添加到线程池的任务先等待