为什么现在()? (客观化)

Why .now()? (Objectify)

为什么我会想要异步加载 Objectify 实体?异步加载到底是什么意思?

根据Objectify documentation about loading,以下加载实体的方式是异步的:

// Simple key fetch, always asynchronous
Result<Thing> th = ofy().load().key(thingKey);

如果我想让负载同步执行,那么我应该这样做:

Thing th = ofy().load().key(thingKey).now(); // added .now()

对我来说,异步意味着操作将在某个未指定的时间稍后发生。对于保存,异步是有意义的,因为数据存储操作可能需要一些时间才能自行完成而不阻塞应用程序代码。

但是对于加载,异步是否意味着加载将在另一个时间发生? Java 这怎么可能?我认为当代码行 Result<Thing> th = ofy().load().key(thingKey); 完成执行时必须更新变量 Result<Thing> th

作为新手,我花了很长时间才弄明白这一点(例如参见 [​​=19=])。

所以我有几个问题:

1] 为什么我要异步加载 Objectify 实体?

2]异步加载到底是什么意思?

3]加载now()和保存now()之间的概念link是什么?

同步负载(source)

Thing th = ofy().load().key(thingKey).now();

同步保存(source)

ofy().save().entity(thing1).now();

4] 为什么同步不是保存和加载的默认行为?

Google Cloud Datasore 旨在为用户提供积极的关系和非关系体验,本质上是两全其美。 Google 数据存储是一个 NoSQL 数据库,它提供 最终一致性 以提高可扩展性,但您也可以选择 强一致性

Google、Balancing Strong and Eventual Consistency with Google Cloud Datastore 撰写的这篇文章将大大有助于回答您的一些问题。它解释了最终一致性模型,该模型是理解数据存储如何在与您的问题相关的幕后工作的关键。

异步操作启动到后端的网络获取,然后让您的代码继续执行。异步操作的优点是您可以 运行 并行执行其中的几个操作:

Result<Thing> th1 = ofy().load().key(thingKey1);
Result<Thing> th2 = ofy().load().key(thingKey2);
Result<Thing> th3 = ofy().load().key(thingKey3);
th1.now();
th2.now();
th3.now();

这比每次都立即调用 now() 要快得多。请注意,这是一个糟糕的示例,因为您可能会使用批处理获取(这也会并行化操作),但您可以同时进行多个查询、保存、删除等 运行ning。

now() 总是强制同步完成,阻塞直到完成。

Google 云支持对支持案例 05483551 的回应:

Java上下文中的“异步”意味着使用“Futures”或类似 Future 的结构。 java[1] 中的 Future 是一个对象,表示在下一行开始在当前线程中执行时不一定需要执行和完成的操作。

对 Java 中异步函数的调用将立即 return 一个 Future,表示承诺后台“线程”将在 computation/network 调用上工作,而下一行的代码继续执行,还不需要那个结果。当在 Future 对象上调用方法 .get() 时,要么结果被 returned,已经及时获得,要么线程将等待直到获得结果,然后将执行传递到下一行.get() 仅在发生这种情况时调用。

在 Objectify 中,避免了 Futures,而是定义了 Result 接口[2],因为与抛出异常相关的原因使得在 Futures 的基础上开发变得很痛苦。然而,它们以几乎相同的方式工作。在常规 Future 具有方法 .get() 的地方,Result 接口(由几个不同的具体 类 实现,具体取决于您正在执行的 Objectify 调用类型)具有 .now(),它检索结果或等待线程直到它可用。

您可能想要异步加载实体的原因是,当您有一个请求处理程序或 API 方法需要稍后在函数中使用一个实体,但也有一些其他的计算要做,不相关到实体。您可以在第一行开始加载实体,获取结果,然后仅在其他不相关的代码执行完毕后才对结果调用 .now()。如果您等待调用 .now() 实际启动加载的时间点,您的响应 handler/API 方法可能只是在等待结果,而不是进行有用的计算。

最后,用于加载的 .now() 和用于保存的 .now() 之间的概念 link 是这两个操作都在后台发生,并且最终只被强制执行,等待执行线程,当 . now() 在通过调用 save() 或 load() return 编辑的结果接口实现对象上调用。

我希望这有助于为您解释 Java Objectify 中的异步结构。如果您有任何其他疑问或问题,请随时在您的回复中包含这些问题,我们很乐意提供帮助。

此致,

尼克 技术解决方案代表 云平台支持

[1] http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html

[2]http://objectify-appengine.googlecode.com/svn/trunk/javadoc/com/googlecode/objectify/Result.html