akka(tell,ask,send)

tell

异步发送一个消息并立即返回。

target.tell(message, getSelf());

在Actor外部,如果没有回复,第二个参数可以为null;

ask

异步发送一条消息并返回一个 Future代表一个可能的回应

forward转发消息

target.forward(result, getContext());

注意

使用ask会造成性能影响,因为当超时是,一些事情需要保持追踪。这需要一些东西来将一个Promise连接进入ActorRef,并且需要通过远程连接可到达的。所以总是使用tell更偏向性能,除非必须才用ask。

如果在角色外部需要一个回复,你可以使用ASK模式描

ask 模式既包含actor也包含future, 所以它是作为一种使用模式,而不是ActorRef的方法:
ask和future上的pipe模式一起使用是一个常用的组合,

final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS));
final ArrayListObject>> futures = new ArrayListObject>>();
futures.add(ask(actorA, "request", 1000)); 
futures.add(ask(actorB, "another request", t)); 
final FutureObject>> aggregate = Futures.sequence(futures,
    system.dispatcher());
final Future transformed = aggregate.map(
    new MapperObject>, Result>() {
      public Result apply(Iterable<Object> coll) {
        final Iterator<Object> it = coll.iterator();
        final String x = (String) it.next();
        final String s = (String) it.next();
        return new Result(x, s);
      }
    }, system.dispatcher());
pipe(transformed, system.dispatcher()).to(actorC);

ask 产生 Future, 两个通过Futures.sequence和map方法组合成一个新的Future,然后用 pipe 在future上安装一个 onComplete-处理器来完成将收集到的 Result 发送到其它actor的动作。使用 ask 将会像tell 一样发送消息给接收方, 接收方必须通过getSender().tell(reply, getSelf()) 发送回应来为返回的 Future 填充数据。ask 操作包括创建一个内部actor来处理回应,必须为这个内部actor指定一个超时期限,过了超时期限内部actor将被销毁以防止内存泄露。

如果一个actor 没有完成future , 它会在超时时限到来时过期, 明确作为一个参数传给ask方法,以 AskTimeoutException来完成Future。

try {
  String result = operation();
  getSender().tell(result, getSelf());
} catch (Exception e) {
  getSender().tell(new akka.actor.Status.Failure(e), getSelf());
  throw e;
}

Future的onComplete, onResult, 或 onTimeout 方法可以用来注册一个回调,以便在Future完成时得到通知。从而提供一种避免阻塞的方法。

使用future回调时,在角色内部要避免使用关闭该角色的引用(不要在回调中调用该角色的方法或访问其可变状态)这会破坏角色的封装,会引用同步bug和race condition, 因为回调会与此角色一同被并发调度。 目前还没有一种编译时的方法能够探测到这种非法访问。

你可能感兴趣的:(技术)