scala葡京娱乐注册-Future和Promise

率先表明同步与异步,阻塞与非阻塞的题目:
Asynchronous vs. Synchronous

上回讲到,游戏逻辑交由Table去测试了,TableServer似乎没有怎么可测的了。

A method call is considered synchronous if the caller cannot make
progress until the method returns a value or throws an exception. On
the other hand, an asynchronous call allows the caller to progress
after a finite number of steps, and the completion of the method may
be signalled via some additional mechanism (it might be a registered
callback, a Future, or a message).
A synchronous API may use blocking to implement synchrony, but this is
not a necessity. A very CPU intensive task might give a similar
behavior as blocking. In general, it is preferred to use asynchronous
APIs, as they guarantee that the system is able to progress.

想了下,TableServer仍旧有点东西可测的,至少我们能够测试API接口是否健康。

Non-blocking vs. Blocking

据此现在补了点TableServer的测试。代码也做了点修改。

We talk about blocking if the delay of one thread can indefinitely
delay some of the other threads. A good example is a resource which
can be used exclusively by one thread using mutual exclusion. If a
thread holds on to the resource indefinitely (for example accidentally
running an infinite loop) other threads waiting on the resource can
not progress. In contrast, non-blocking means that no thread is able
to indefinitely delay others.
Non-blocking operations are preferred to blocking ones, as the overall
progress of the system is not trivially guaranteed when it contains
blocking operations.

其余顺便提一下,要是在一个节点只用1个Registry提供Player/Table等多种挂号的话,最好分装多少个Global注册的

以上文献摘自akka文档,一个措施之所以被叫做同步方法,是因为直至该方法重回某值或者抛出相当,该办法的调用者才能拿到结果(make progress)。假设一个异步调用需要通过额外的体制(比如callback,Future,message)。假使一个线程的推移导致了另一个(一些)线程的推移,那么久出现了不通(blocking)。一个例证就是一个资源被一个线程所独占,那么其他线程需要拭目以待这多少个线程释放资源才能继续执行。

API并扩大再上一层的API供统一行使或者会更好点,这样毫无每个需要的地点都做。

scala中的FuturePromise都是非阻塞的进行,既可以因而回调函数获取结果,但是也可以通过阻塞的主意串行获取结果。

这一部分我们处理,因为其实不难。

Future

一个Future会所有一个值,虽然这么些值在将来某个时间点才可用。

  1. 若果统计未形成,那么那个Future就未成功。
  2. 假使总括完成(拿到结果要么特别),那些Future就完了了。

Future唯其如此被选派一次,一旦Future给定了一个值或特别,它的结果不可以改改。

object Main extends App {
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.Future
  val f:Future[Int]=Future{
    Thread.sleep(100)//模拟某个耗时操作 比如网络请求
    println("haha")
    10
  }
  Thread.sleep(1000)
}
  //haha

 

异步方法拿到结果

目标获取结果,而不是决定实施过程。
scala提供了onSuccess等回调函数。其签名为:def onComplete[U](f: Try[T] => U)(implicit executor: ExecutionContext): Unit

f.onComplete({
    case Success(i) => println(i)
    case Failure(e) => e.printStackTrace()
  })

上述代码应用偏函数格局,或者:

  f.onComplete(result=>result match {
    case Success(i)=>println(i)
    case Failure(e)=>e.printStackTrace()
  })

仍是可以注册六个回调:

f.onComplete(result=>result match {
    case Success(i)=>println(i)
  })
f.onComplete(result=>result match {
    case Success(i)=>println(i+20)
  })

注:两个回调函数之间并不保证实施各种

代码已经付出。

协办方法得到结果

通过Await.result可以协同获取结果,或者逾期或者卓殊。Await.ready等候总括完成,不回去结果。

val r=Await.result(f,Duration.Inf) //Await.result(f,1 seconds)

Promise

除了通过Future.apply创建Future目的,还可以够使用Promise.future。如果说Future是一个只读的,值还没统计的占位符。那么Promise就是一个可写的,单次指派的器皿。Promise可以经过调用success代表Future成功完成,failure办法抛出分外。或者更抽象的complete

object Main extends App {
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.{Future,Promise}
//  import scala.concurrent.duration._
  val p=Promise[Int]
  val f=p.future
  val producer=Future{
    p complete Try{
      100
    }
  }
  val consumer=Future{
    f onComplete{
      case Success(i)=>println(i)
      case Failure(e)=>e.printStackTrace()
    }
  }
  Thread.sleep(1000)
}