diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index 97e36086db..c6f6333822 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -82,17 +82,25 @@ abstract class ActorRef extends java.lang.Comparable[ActorRef] with Serializable final def tell(msg: Any, sender: ActorRef): Unit = this.!(msg)(sender) /** - * Akka Java API.
+ * Akka Java API. + * * Sends a message asynchronously returns a future holding the eventual reply message. - * + * * NOTE: * Use this method with care. In most cases it is better to use 'tell' together with the sender * parameter to implement non-blocking request/response message exchanges. - * + * * If you are sending messages usingask and using blocking operations on the Future, such as
* 'get', then you have to use getContext().sender().tell(...)
* in the target actor to send a reply message to the original sender, and thereby completing the Future,
* otherwise the sender will block until the timeout expires.
+ *
+ * When using future callbacks, inside actors you need to carefully avoid closing over
+ * the containing actor’s reference, i.e. do not call methods or access mutable state
+ * on the enclosing actor from within the callback. This would break the actor
+ * encapsulation and may introduce synchronization bugs and race conditions because
+ * the callback will be scheduled concurrently to the enclosing actor. Unfortunately
+ * there is not yet a way to detect these illegal accesses at compile time.
*/
def ask(message: AnyRef, timeout: Timeout): Future[AnyRef] = ?(message, timeout).asInstanceOf[Future[AnyRef]]
@@ -154,11 +162,18 @@ trait ScalaActorRef { ref: ActorRef ⇒
* NOTE:
* Use this method with care. In most cases it is better to use '!' together with implicit or explicit
* sender parameter to implement non-blocking request/response message exchanges.
- *
+ *
* If you are sending messages using ask and using blocking operations on the Future, such as
* 'get', then you have to use getContext().sender().tell(...)
* in the target actor to send a reply message to the original sender, and thereby completing the Future,
* otherwise the sender will block until the timeout expires.
+ *
+ * When using future callbacks, inside actors you need to carefully avoid closing over
+ * the containing actor’s reference, i.e. do not call methods or access mutable state
+ * on the enclosing actor from within the callback. This would break the actor
+ * encapsulation and may introduce synchronization bugs and race conditions because
+ * the callback will be scheduled concurrently to the enclosing actor. Unfortunately
+ * there is not yet a way to detect these illegal accesses at compile time.
*/
def ?(message: Any)(implicit timeout: Timeout): Future[Any]
diff --git a/akka-docs/java/untyped-actors.rst b/akka-docs/java/untyped-actors.rst
index 2e6e68b215..4324aadf19 100644
--- a/akka-docs/java/untyped-actors.rst
+++ b/akka-docs/java/untyped-actors.rst
@@ -268,7 +268,7 @@ Gives you a way to avoid blocking.
the containing actor’s reference, i.e. do not call methods or access mutable state
on the enclosing actor from within the callback. This would break the actor
encapsulation and may introduce synchronization bugs and race conditions because
- the callback will be scheduled concurrently to the enclosing actor. Unfortunately
+ the callback will be scheduled concurrently to the enclosing actor. Unfortunately
there is not yet a way to detect these illegal accesses at compile time. See also:
:ref:`jmm-shared-state`
diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst
index 27aa60ea3a..eb4649e2c8 100644
--- a/akka-docs/scala/actors.rst
+++ b/akka-docs/scala/actors.rst
@@ -316,7 +316,7 @@ Gives you a way to avoid blocking.
the containing actor’s reference, i.e. do not call methods or access mutable state
on the enclosing actor from within the callback. This would break the actor
encapsulation and may introduce synchronization bugs and race conditions because
- the callback will be scheduled concurrently to the enclosing actor. Unfortunately
+ the callback will be scheduled concurrently to the enclosing actor. Unfortunately
there is not yet a way to detect these illegal accesses at compile time.
See also: :ref:`jmm-shared-state`